*** empty log message ***
[yaffs/.git] / yaffs_fileem.c
index a137fb47fd14f79c498add26f9b6693fd0c72002..b850581d9b1e3da6ddee81f6fb87bf522a240786 100644 (file)
@@ -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 <fcntl.h>
 #include <string.h>
 
-#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))
 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;
+}