*** empty log message ***
[yaffs/.git] / yaffs_guts.c
index dfef9def4c17a10e89afb2e304f93993baf5d068..133dd15cc1fb51f3a3e6cd6fa4ff87f48a22ae26 100644 (file)
  */
  //yaffs_guts.c
 
-const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.22 2003-03-11 05:16:53 charles Exp $";
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.26 2003-05-20 23:20:53 charles Exp $";
 
 #include "yportenv.h"
 
 #include "yaffsinterface.h"
 #include "yaffs_guts.h"
 
-
-
-
 #define YAFFS_PASSIVE_GC_CHUNKS 2
 
+#if 0
+// Use Steven Hill's ECC struff instead
 // External functions for ECC on data
 void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
 int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-
+#define yaffs_ECCCalculate(data,ecc) nand_calculate_ecc(data,ecc)
+#define yaffs_ECCCorrect(data,read_ecc,calc_ecc) nand_correct_ecc(data,read_ecc,calc_ecc)
+#else
+#include "yaffs_ecc.h"
+#endif
 
 // countBits is a quick way of counting the number of bits in a byte.
 // ie. countBits[n] holds the number of 1 bits in a byte with the value n.
@@ -239,10 +242,10 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
                int eccResult1,eccResult2;
                __u8 calcEcc[3];
                 
-                       nand_calculate_ecc(data,calcEcc);
-                       eccResult1 = nand_correct_data (data,spare->ecc1, calcEcc);
-                       nand_calculate_ecc(&data[256],calcEcc);
-                       eccResult2 = nand_correct_data (&data[256],spare->ecc2, calcEcc);
+                       yaffs_ECCCalculate(data,calcEcc);
+                       eccResult1 = yaffs_ECCCorrect (data,spare->ecc1, calcEcc);
+                       yaffs_ECCCalculate(&data[256],calcEcc);
+                       eccResult2 = yaffs_ECCCorrect(&data[256],spare->ecc2, calcEcc);
 
                        if(eccResult1>0)
                        {
@@ -582,8 +585,8 @@ void yaffs_SetObjectName(yaffs_Object *obj, const char *name)
 
 void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
 {
-       nand_calculate_ecc (data , spare->ecc1);
-       nand_calculate_ecc (&data[256] , spare->ecc2);
+       yaffs_ECCCalculate(data , spare->ecc1);
+       yaffs_ECCCalculate(&data[256] , spare->ecc2);
 }
 
 void yaffs_CalcTagsECC(yaffs_Tags *tags)
@@ -3128,6 +3131,7 @@ static void yaffs_FlushFilesChunkCache(yaffs_Object *obj)
                                                                                                                        cache->nBytes,1);
 
                                cache->dirty = 0;
+                               cache->object = NULL;
                        }
                
                } while(cache && chunkWritten > 0);
@@ -3160,10 +3164,14 @@ static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev)
                        if(!dev->srCache[i].object)
                        {
                                //T(("Grabbing empty %d\n",i));
+                               
+                               //printf("Grabbing empty %d\n",i);
                        
                                return &dev->srCache[i];
                        }
                }
+               
+               return NULL;
        
                theOne = -1; 
                usage = 0; // just to stop the compiler grizzling
@@ -3180,6 +3188,9 @@ static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev)
                }
        
                //T(("Grabbing non-empty %d\n",theOne));
+               
+               //if(theOne >= 0) printf("Grabbed non-empty cache %d\n",theOne);
+               
                return  theOne >= 0 ?  &dev->srCache[theOne] : NULL;
        }
        else
@@ -3196,6 +3207,7 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
        yaffs_Object *theObj;
        int usage;
        int i;
+       int pushout;
        
        if(dev->nShortOpCaches > 0)
        {
@@ -3212,6 +3224,8 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
                
                        theObj = dev->srCache[0].object;
                        usage = dev->srCache[0].lastUse;
+                       cache = &dev->srCache[0];
+                       pushout = 0;
        
                        for(i = 1; i < dev->nShortOpCaches; i++)
                        {
@@ -3220,15 +3234,27 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
                                {
                                        usage  = dev->srCache[i].lastUse;
                                        theObj = dev->srCache[i].object;
+                                       cache = &dev->srCache[i];
+                                       pushout = i;
                                }
                        }
                
-                       yaffs_FlushFilesChunkCache(theObj);
+                       if(!cache || cache->dirty)
+                       {
+                       
+                               //printf("Dirty ");
+                               yaffs_FlushFilesChunkCache(theObj);
                
-                       // Try again
-                       cache = yaffs_GrabChunkCacheWorker(dev);
+                               // Try again
+                               cache = yaffs_GrabChunkCacheWorker(dev);
+                       }
+                       else
+                       {
+                               //printf(" pushout %d\n",pushout);
+                       }
+                       
                }
-       
+
                return cache;
        }
        else
@@ -3346,6 +3372,7 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nB
        int nToCopy;
        int n = nBytes;
        int nDone = 0;
+       yaffs_ChunkCache *cache;
        
        yaffs_Device *dev;
        
@@ -3367,14 +3394,18 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nB
                        nToCopy = YAFFS_BYTES_PER_CHUNK - start;
                }
        
-               if(nToCopy != YAFFS_BYTES_PER_CHUNK)
+               cache = yaffs_FindChunkCache(in,chunk);
+               
+               // If the chunk is already in the cache or it is less than a whole chunk
+               // then use the cache (if there is caching)
+               // else bypass the cache.
+               if( cache || nToCopy != YAFFS_BYTES_PER_CHUNK)
                {
-                       // An incomplete start or end chunk (or maybe both start and end chunk)
                        if(dev->nShortOpCaches > 0)
                        {
-                               yaffs_ChunkCache *cache;
+                               
                                // If we can't find the data in the cache, then load it up.
-                               cache = yaffs_FindChunkCache(in,chunk);
+                               
                                if(!cache)
                                {
                                        cache = yaffs_GrabChunkCache(in->myDev);
@@ -3592,7 +3623,7 @@ int yaffs_ResizeFile(yaffs_Object *in, int newSize)
                        // using yaffs_DeleteChunk
 
                        chunkId = yaffs_FindAndDeleteChunkInFile(in,i,NULL);
-                       if(chunkId <= 0 || chunkId >= (dev->endBlock * 32))
+                       if(chunkId < (dev->startBlock * 32) || chunkId >= ((dev->endBlock+1) * 32))
                        {
                                //T(("Found daft chunkId %d for %d\n",chunkId,i));
                        }
@@ -4782,7 +4813,7 @@ int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
        }
        
        
-       printf("___________ nFreeChunks is %d nFree is %d\n",dev->nFreeChunks,nFree);   
+       // printf("___________ nFreeChunks is %d nFree is %d\n",dev->nFreeChunks,nFree);        
 
        if(nFree < 0) nFree = 0;
 
@@ -4797,6 +4828,7 @@ int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
        int nFree;
        int pending;
        int b;
+       int nDirtyCacheChunks=0;
        
        yaffs_BlockInfo *blk;
        
@@ -4844,6 +4876,20 @@ int  yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
 
        nFree += pending;
        
+       // Now count the number of dirty chunks in the cache and subtract those
+       
+       {
+               int i;
+               for(i = 0; i < dev->nShortOpCaches; i++)
+               {
+                       if(dev->srCache[i].dirty) nDirtyCacheChunks++;
+               }
+       }
+       
+       nFree -= nDirtyCacheChunks;
+       
+       nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
+       
        if(nFree < 0) nFree = 0;
 
        return nFree;