*/
//yaffs_guts.c
+const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.10 2002-09-27 20:50:50 charles Exp $";
+
#include "yportenv.h"
#include "yaffsinterface.h"
// Local prototypes
static int yaffs_CheckObjectHashSanity(yaffs_Device *dev);
static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr);
-static void yaffs_GetTagsFromSpare(yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr);
+static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr);
static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkInNAND, int inScan);
static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type);
if(eccResult1>0)
{
T((TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND));
+ dev->eccFixed++;
}
else if(eccResult1<0)
{
T((TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND));
+ dev->eccUnfixed++;
}
if(eccResult2>0)
{
T((TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND));
+ dev->eccFixed++;
}
else if(eccResult2<0)
{
T((TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND));
+ dev->eccUnfixed++;
}
if(eccResult1 || eccResult2)
}
-void yaffs_CheckECCOnTags(yaffs_Tags *tags)
+int yaffs_CheckECCOnTags(yaffs_Tags *tags)
{
unsigned ecc = tags->ecc;
ecc ^= tags->ecc;
- if(ecc)
+ if(ecc && ecc <= 64)
{
- // Needs fixing
+ // TODO: Handle the failure better. Retire?
unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes;
ecc--;
// Now recvalc the ecc
yaffs_CalcTagsECC(tags);
+
+ return 1; // recovered error
+ }
+ else if(ecc)
+ {
+ // Wierd ecc failure value
+ // TODO Need to do somethiong here
+ return -1; //unrecovered error
}
+
+ return 0;
}
yaffs_ReadChunkFromNAND(dev,oldChunk,buffer, &spare,1);
- yaffs_GetTagsFromSpare(&spare,&tags);
+ yaffs_GetTagsFromSpare(dev,&spare,&tags);
+
tags.serialNumber++;
yaffs_LoadTagsIntoSpare(&spare,&tags);
sparePtr->tagByte7 = tu->asBytes[7];
}
-static void yaffs_GetTagsFromSpare(yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr)
+static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr)
{
yaffs_TagsUnion *tu = (yaffs_TagsUnion *)tagsPtr;
+ int result;
tu->asBytes[0]= sparePtr->tagByte0;
tu->asBytes[1]= sparePtr->tagByte1;
tu->asBytes[6]= sparePtr->tagByte6;
tu->asBytes[7]= sparePtr->tagByte7;
- yaffs_CheckECCOnTags(tagsPtr);
+ result = yaffs_CheckECCOnTags(tagsPtr);
+ if(result> 0)
+ {
+ dev->tagsEccFixed++;
+ }
+ else if(result <0)
+ {
+ dev->tagsEccUnfixed++;
+ }
}
static void yaffs_SpareInitialise(yaffs_Spare *spare)
if(yaffs_ReadChunkFromNAND(dev,chunkInNAND,NULL,&spare,1) == YAFFS_OK)
{
*chunkDeleted = (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0;
- yaffs_GetTagsFromSpare(&spare,tags);
+ yaffs_GetTagsFromSpare(dev,&spare,tags);
return YAFFS_OK;
}
else
#ifdef CONFIG_YAFFS_SHORT_OP_CACHE
yaffs_ChunkCache *cache;
-#else
- __u8 localBuffer[YAFFS_BYTES_PER_CHUNK];
#endif
+
+ __u8 localBuffer[YAFFS_BYTES_PER_CHUNK];
int chunk;
int start;
}
else
{
+#ifdef WIN32
+ // Under WinCE can't do direct transfer. Need to use a local buffer.
+ // This is because we otherwise screw up WinCE's memory mapper
+ yaffs_ReadChunkDataFromObject(in,chunk,localBuffer);
+ memcpy(buffer,localBuffer,YAFFS_BYTES_PER_CHUNK);
+#else
// A full chunk. Read directly into the supplied buffer.
yaffs_ReadChunkDataFromObject(in,chunk,buffer);
+#endif
}
n -= nToCopy;
}
else
{
+
+#ifdef WIN32
+ // Under WinCE can't do direct transfer. Need to use a local buffer.
+ // This is because we otherwise screw up WinCE's memory mapper
+ memcpy(localBuffer,buffer,YAFFS_BYTES_PER_CHUNK);
+ chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,localBuffer,YAFFS_BYTES_PER_CHUNK,0);
+#else
// A full chunk. Write directly from the supplied buffer.
chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,buffer,YAFFS_BYTES_PER_CHUNK,0);
+#endif
//T(("Write to chunk %d %d\n",chunk,chunkWritten));
}
// This block looks ok, now what's in this chunk?
- yaffs_GetTagsFromSpare(&spare,&tags);
+ yaffs_GetTagsFromSpare(dev,&spare,&tags);
if(yaffs_CountBits(spare.pageStatus) < 6)
{
dev->nDeletedFiles = 0;
dev->nBackgroundDeletions=0;
dev->nUnlinkedFiles = 0;
+ dev->eccFixed=0;
+ dev->eccUnfixed=0;
+ dev->tagsEccFixed=0;
+ dev->tagsEccUnfixed=0;
yaffs_InitialiseBlocks(dev,nBlocks);