X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs%2F.git;a=blobdiff_plain;f=yaffs_fileem.c;h=3ee50eb739ab6a39f32bff4259b985a0ec331c14;hp=a03461017bd5c76de5858c572135e1511ed7db99;hb=7b5f93e758d963355b31ce0a1f0eafa16074f35d;hpb=11b48ba07062b2975286d468b9a75f7d06293d78 diff --git a/yaffs_fileem.c b/yaffs_fileem.c index a034610..3ee50eb 100644 --- a/yaffs_fileem.c +++ b/yaffs_fileem.c @@ -28,6 +28,8 @@ #define FILE_SIZE_IN_MEG 2 +// #define YAFFS_ERROR_TESTING + #define BLOCK_SIZE (32 * 528) #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) #define FILE_SIZE_IN_BLOCKS (FILE_SIZE_IN_MEG * BLOCKS_PER_MEG) @@ -37,6 +39,97 @@ static int h; static __u8 ffChunk[528]; +static int eraseDisplayEnabled; + +static int markedBadBlocks[] = { 1, 4, -1}; + +static int IsAMarkedBadBlock(int blk) +{ +#if YAFFS_ERROR_TESTING + int *m = markedBadBlocks; + + while(*m >= 0) + { + if(*m == blk) return 1; + m++; + } +#endif + return 0; +} + + +static __u8 yaffs_WriteFailCorruption(int chunkInNAND) +{ +#if YAFFS_ERROR_TESTING + + // 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 + + + } +#endif + return 0; +} + +static void yaffs_ModifyWriteData(int chunkInNAND,__u8 *data) +{ +#if YAFFS_ERROR_TESTING + if(data) + { + *data ^= yaffs_WriteFailCorruption(chunkInNAND); + } +#endif +} + +static __u8 yaffs_ReadFailCorruption(int chunkInNAND) +{ + switch(chunkInNAND) + { +#if YAFFS_ERROR_TESTING + case 500: + return 3;// ding two bits + case 700: + case 750: + return 1;// ding one bit + +#endif + default: return 0; + + } +} + +static void yaffs_ModifyReadData(int chunkInNAND,__u8 *data) +{ +#if YAFFS_ERROR_TESTING + if(data) + { + *data ^= yaffs_ReadFailCorruption(chunkInNAND); + } +#endif +} + + + static void CheckInit(yaffs_Device *dev) @@ -44,13 +137,18 @@ static void CheckInit(yaffs_Device *dev) static int initialised = 0; int length; + int nWritten; if(!initialised) { memset(ffChunk,0xFF,528); +//#ifdef YAFFS_DUMP +// h = open("yaffs-em-file" , O_RDONLY); +//#else h = open("yaffs-em-file" , O_RDWR | O_CREAT, S_IREAD | S_IWRITE); +//#endif if(h < 0) { perror("Fatal error opening yaffs emulation file"); @@ -59,22 +157,33 @@ static void CheckInit(yaffs_Device *dev) initialised = 1; length = lseek(h,0,SEEK_END); - if(length != FILE_SIZE_IN_BYTES) + nWritten = 528; + while(length < FILE_SIZE_IN_BYTES && nWritten == 528) { - // Create file contents - int i; - - printf("Creating emulation file...\n"); - for(i = 0; i < FILE_SIZE_IN_BLOCKS; i++) - { - yaffs_FEEraseBlockInNAND(dev,i); - } + write(h,ffChunk,528); + length = lseek(h,0,SEEK_END); } + if(nWritten != 528) + { + perror("Fatal error expanding yaffs emulation file"); + exit(1); + + } + + close(h); + +#ifdef YAFFS_DUMP + h = open("yaffs-em-file" , O_RDONLY); +#else + h = open("yaffs-em-file" , O_RDWR | O_CREAT, S_IREAD | S_IWRITE); +#endif } } int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare) { + __u8 localData[512]; + int pos; pos = chunkInNAND * 528; @@ -84,8 +193,10 @@ int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, 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; @@ -113,6 +224,7 @@ int yaffs_FEReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaf { lseek(h,pos,SEEK_SET); read(h,data,512); + yaffs_ModifyReadData(chunkInNAND,data); } pos += 512; @@ -133,13 +245,23 @@ int yaffs_FEEraseBlockInNAND(yaffs_Device *dev,int blockInNAND) 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; }