X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs%2F.git;a=blobdiff_plain;f=yaffs_guts.c;h=5784d7956cc63d008c4df3045968e0839c90f70a;hp=cfe955f8ca306e7298b24a56f1534a42171557a3;hb=64a12f248950e23dd994ff29fd090480e0921930;hpb=1dea37b139c892671df123e8ad4204ab4dc20fa5 diff --git a/yaffs_guts.c b/yaffs_guts.c index cfe955f..5784d79 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -14,22 +14,25 @@ */ //yaffs_guts.c -const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.20 2003-01-31 03:30:33 charles Exp $"; +const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.25 2003-05-20 22:30:35 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. @@ -216,10 +219,6 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, int retVal; yaffs_Spare localSpare; - __u8 calcEcc[3]; - int eccResult1,eccResult2; - struct yaffs_NANDSpare nspare; - dev->nPageReads++; @@ -240,10 +239,13 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, { // Do ECC correction //Todo handle any errors - 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); + int eccResult1,eccResult2; + __u8 calcEcc[3]; + + 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) { @@ -276,6 +278,8 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, } else { + // Must allocate enough memory for spare+2*sizeof(int) for ecc results from device. + struct yaffs_NANDSpare nspare; retVal = dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare*)&nspare); memcpy (spare, &nspare, sizeof(yaffs_Spare)); if(data && doErrorCorrection) @@ -298,7 +302,7 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND)); } - if(nspare.eccres2 || nspare.eccres2) + if(nspare.eccres1 || nspare.eccres2) { // Hoosterman, we had a data problem on this page yaffs_HandleReadDataError(dev,chunkInNAND); @@ -316,12 +320,10 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND static int init = 0; static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK]; static __u8 data[YAFFS_BYTES_PER_CHUNK]; - static __u8 spare[16]; - - - dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare *)spare); - - + // Might as well always allocate the larger size for dev->useNANDECC == true; + static __u8 spare[sizeof(struct yaffs_NANDSpare)]; + + dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare *)spare); if(!init) { @@ -583,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) @@ -1853,7 +1855,7 @@ int yaffs_RenameObject(yaffs_Object *oldDir, const char *oldName, yaffs_Object * yaffs_Object *obj; int force = 0; -#ifdef YAFFS_CASE_INSENSITIVE +#ifdef CONFIG_YAFFS_CASE_INSENSITIVE // Special case for WinCE. // While look-up is case insensitive, the name isn't. // THerefore we might want to change x.txt to X.txt @@ -3129,6 +3131,7 @@ static void yaffs_FlushFilesChunkCache(yaffs_Object *obj) cache->nBytes,1); cache->dirty = 0; + cache->object = NULL; } } while(cache && chunkWritten > 0); @@ -3161,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 @@ -3181,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 @@ -3197,6 +3207,7 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev) yaffs_Object *theObj; int usage; int i; + int pushout; if(dev->nShortOpCaches > 0) { @@ -3213,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++) { @@ -3221,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 @@ -3347,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; @@ -3368,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); @@ -3593,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)); } @@ -4783,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; @@ -4798,6 +4828,7 @@ int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev) int nFree; int pending; int b; + int nDirtyCacheChunks=0; yaffs_BlockInfo *blk; @@ -4845,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;