Consolidate unlinked file handling durinit init to take care of restored checkpoint...
[yaffs2.git] / yaffs_tagscompat.c
index 61880d5..f6c4053 100644 (file)
@@ -1,21 +1,20 @@
 /*
- * YAFFS: Yet another FFS. A NAND-flash specific file system. 
- * yaffs_tagscompat.h: Tags compatability layer to use YAFFS1 formatted NAND.
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002 Aleph One Ltd.
+ * Copyright (C) 2002-2007 Aleph One Ltd.
+ *   for Toby Churchill Ltd and Brightstar Engineering
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
- *
- * $Id: yaffs_tagscompat.c,v 1.6 2005-08-11 02:33:03 marty Exp $
  */
 
 #include "yaffs_guts.h"
 #include "yaffs_tagscompat.h"
 #include "yaffs_ecc.h"
+#include "yaffs_getblockinfo.h"
 
 static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND);
 #ifdef NOTYET
@@ -47,7 +46,7 @@ static const char yaffs_countBitsTable[256] = {
        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
 };
 
-static int yaffs_CountBits(__u8 x)
+int yaffs_CountBits(__u8 x)
 {
        int retVal;
        retVal = yaffs_countBitsTable[x];
@@ -213,13 +212,13 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
                        if (eccResult1 > 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error fix performed on chunk %d:0"
+                                  ("**>>yaffs ecc error fix performed on chunk %d:0"
                                    TENDSTR), chunkInNAND));
                                dev->eccFixed++;
                        } else if (eccResult1 < 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error unfixed on chunk %d:0"
+                                  ("**>>yaffs ecc error unfixed on chunk %d:0"
                                    TENDSTR), chunkInNAND));
                                dev->eccUnfixed++;
                        }
@@ -227,13 +226,13 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
                        if (eccResult2 > 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error fix performed on chunk %d:1"
+                                  ("**>>yaffs ecc error fix performed on chunk %d:1"
                                    TENDSTR), chunkInNAND));
                                dev->eccFixed++;
                        } else if (eccResult2 < 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error unfixed on chunk %d:1"
+                                  ("**>>yaffs ecc error unfixed on chunk %d:1"
                                    TENDSTR), chunkInNAND));
                                dev->eccUnfixed++;
                        }
@@ -254,6 +253,9 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
                /* Must allocate enough memory for spare+2*sizeof(int) */
                /* for ecc results from device. */
                struct yaffs_NANDSpare nspare;
+               
+               memset(&nspare,0,sizeof(nspare));
+               
                retVal =
                    dev->readChunkFromNAND(dev, chunkInNAND, data,
                                           (yaffs_Spare *) & nspare);
@@ -262,24 +264,24 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
                        if (nspare.eccres1 > 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error fix performed on chunk %d:0"
+                                  ("**>>mtd ecc error fix performed on chunk %d:0"
                                    TENDSTR), chunkInNAND));
                        } else if (nspare.eccres1 < 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error unfixed on chunk %d:0"
+                                  ("**>>mtd ecc error unfixed on chunk %d:0"
                                    TENDSTR), chunkInNAND));
                        }
 
                        if (nspare.eccres2 > 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error fix performed on chunk %d:1"
+                                  ("**>>mtd ecc error fix performed on chunk %d:1"
                                    TENDSTR), chunkInNAND));
                        } else if (nspare.eccres2 < 0) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
-                                  ("**>>ecc error unfixed on chunk %d:1"
+                                  ("**>>mtd ecc error unfixed on chunk %d:1"
                                    TENDSTR), chunkInNAND));
                        }
 
@@ -338,7 +340,7 @@ static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND)
        int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
 
        /* Mark the block for retirement */
-       yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1;
+       yaffs_GetBlockInfo(dev, blockInNAND + dev->blockOffset)->needsRetiring = 1;
        T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
          (TSTR("**>>Block %d marked for retirement" TENDSTR), blockInNAND));
 
@@ -416,7 +418,16 @@ int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev,
        } else {
                tags.objectId = eTags->objectId;
                tags.chunkId = eTags->chunkId;
-               tags.byteCount = eTags->byteCount;
+
+               tags.byteCountLSB = eTags->byteCount & 0x3ff;
+               
+               if(dev->nDataBytesPerChunk >= 1024){
+                       tags.byteCountMSB = (eTags->byteCount >> 10) & 3;
+               } else {
+                       tags.byteCountMSB = 3;
+               }
+               
+
                tags.serialNumber = eTags->serialNumber;
 
                if (!dev->useNANDECC && data) {
@@ -437,10 +448,10 @@ int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
 
        yaffs_Spare spare;
        yaffs_Tags tags;
-       yaffs_ECCResult eccResult;
+       yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_UNKNOWN;
 
        static yaffs_Spare spareFF;
-       static int init;
+       static int init = 0;
 
        if (!init) {
                memset(&spareFF, 0xFF, sizeof(spareFF));
@@ -455,20 +466,26 @@ int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
                        int deleted =
                            (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0;
 
-                       yaffs_GetTagsFromSpare(dev, &spare, &tags);
-
                        eTags->chunkDeleted = deleted;
-                       eTags->objectId = tags.objectId;
-                       eTags->chunkId = tags.chunkId;
-                       eTags->byteCount = tags.byteCount;
-                       eTags->serialNumber = tags.serialNumber;
                        eTags->eccResult = eccResult;
                        eTags->blockBad = 0;    /* We're reading it */
                        /* therefore it is not a bad block */
-
                        eTags->chunkUsed =
                            (memcmp(&spareFF, &spare, sizeof(spareFF)) !=
                             0) ? 1 : 0;
+
+                       if (eTags->chunkUsed) {
+                               yaffs_GetTagsFromSpare(dev, &spare, &tags);
+
+                               eTags->objectId = tags.objectId;
+                               eTags->chunkId = tags.chunkId;
+                               eTags->byteCount = tags.byteCountLSB;
+
+                               if(dev->nDataBytesPerChunk >= 1024)
+                                       eTags->byteCount |= (((unsigned) tags.byteCountMSB) << 10);
+
+                               eTags->serialNumber = tags.serialNumber;
+                       }
                }
 
                return YAFFS_OK;
@@ -497,9 +514,9 @@ int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
 }
 
 int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
-                                         int blockNo, yaffs_BlockState *
-                                         state,
-                                         int *sequenceNumber)
+                                         int blockNo,
+                                         yaffs_BlockState *state,
+                                         __u32 *sequenceNumber)
 {
 
        yaffs_Spare spare0, spare1;