From f4fcac8940762ee7a3d606ddb3dd4ab7d9ac7868 Mon Sep 17 00:00:00 2001 From: charles Date: Sat, 25 Jun 2005 03:22:23 +0000 Subject: [PATCH] Changes to allow usage of block zero --- direct/yaffscfg.c | 4 +-- yaffs_fs.c | 6 ++-- yaffs_guts.c | 91 ++++++++++++++++++++++++++++------------------- yaffs_guts.h | 9 +++-- 4 files changed, 66 insertions(+), 44 deletions(-) diff --git a/direct/yaffscfg.c b/direct/yaffscfg.c index 83f2277..dfa1b13 100644 --- a/direct/yaffscfg.c +++ b/direct/yaffscfg.c @@ -74,7 +74,7 @@ int yaffs_StartUp(void) ramDev.nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; ramDev.nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; ramDev.nReservedBlocks = 2; // Set this smaller for RAM - ramDev.startBlock = 1; // Can't use block 0 + ramDev.startBlock = 0; // Can now use block zero ramDev.endBlock = 127; // Last block in 2MB. ramDev.useNANDECC = 1; ramDev.nShortOpCaches = 0; // Disable caching on this device. @@ -88,7 +88,7 @@ int yaffs_StartUp(void) bootDev.nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; bootDev.nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; bootDev.nReservedBlocks = 5; - bootDev.startBlock = 1; // Can't use block 0 + bootDev.startBlock = 0; // Can now use block zero bootDev.endBlock = 127; // Last block in 2MB. bootDev.useNANDECC = 0; // use YAFFS's ECC bootDev.nShortOpCaches = 10; // Use caches diff --git a/yaffs_fs.c b/yaffs_fs.c index 86a2559..715a71b 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -29,7 +29,7 @@ */ -const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.39 2005-04-24 08:54:36 charles Exp $"; +const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.40 2005-06-25 03:22:23 charles Exp $"; extern const char *yaffs_guts_c_version; @@ -1326,7 +1326,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl dev->genericDevice = NULL; // Not used for RAM emulation. nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); - dev->startBlock = 1; // Don't use block 0 + dev->startBlock = 0; dev->endBlock = nBlocks - 1; dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; @@ -1426,7 +1426,7 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl // Set up the memory size parameters.... nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); - dev->startBlock = 1; // Don't use block 0 + dev->startBlock = 0; dev->endBlock = nBlocks - 1; dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; diff --git a/yaffs_guts.c b/yaffs_guts.c index e4a61c0..8f09a10 100644 --- a/yaffs_guts.c +++ b/yaffs_guts.c @@ -14,7 +14,7 @@ */ //yaffs_guts.c -const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.41 2005-04-24 08:54:36 charles Exp $"; +const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.42 2005-06-25 03:22:23 charles Exp $"; #include "yportenv.h" @@ -120,12 +120,12 @@ static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId); static __inline __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk) { - if(blk < dev->startBlock || blk > dev->endBlock) + if(blk < dev->internalStartBlock || blk > dev->internalEndBlock) { T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),blk)); YBUG(); } - return dev->chunkBits + (dev->chunkBitmapStride * (blk - dev->startBlock)); + return dev->chunkBits + (dev->chunkBitmapStride * (blk - dev->internalStartBlock)); } static __inline__ void yaffs_ClearChunkBits(yaffs_Device *dev,int blk) @@ -170,12 +170,12 @@ static __inline__ int yaffs_StillSomeChunkBits(yaffs_Device *dev,int blk) // Function to manipulate block info static __inline__ yaffs_BlockInfo* yaffs_GetBlockInfo(yaffs_Device *dev, int blk) { - if(blk < dev->startBlock || blk > dev->endBlock) + if(blk < dev->internalStartBlock || blk > dev->internalEndBlock) { T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),blk)); YBUG(); } - return &dev->blockInfo[blk - dev->startBlock]; + return &dev->blockInfo[blk - dev->internalStartBlock]; } @@ -198,14 +198,14 @@ yaffs_Object *yaffs_LostNFound(yaffs_Device *dev) static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare) { - if(chunkInNAND < dev->startBlock * dev->nChunksPerBlock) + if(chunkInNAND < dev->internalStartBlock * dev->nChunksPerBlock) { T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs chunk %d is not valid" TENDSTR),chunkInNAND)); return YAFFS_FAIL; } dev->nPageWrites++; - return dev->writeChunkToNAND(dev,chunkInNAND,data,spare); + return dev->writeChunkToNAND(dev,chunkInNAND - dev->chunkOffset,data,spare); } @@ -234,7 +234,7 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, if(!dev->useNANDECC) { - retVal = dev->readChunkFromNAND(dev,chunkInNAND,data,spare); + retVal = dev->readChunkFromNAND(dev,chunkInNAND - dev->chunkOffset,data,spare); if(data && doErrorCorrection) { // Do ECC correction @@ -249,23 +249,23 @@ int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, if(eccResult1>0) { - T(YAFFS_TRACE_ERROR, (TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR, (TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset)); dev->eccFixed++; } else if(eccResult1<0) { - T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset)); dev->eccUnfixed++; } if(eccResult2>0) { - T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset)); dev->eccFixed++; } else if(eccResult2<0) { - T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset)); dev->eccUnfixed++; } @@ -280,26 +280,26 @@ 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; - retVal = dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare*)&nspare); + retVal = dev->readChunkFromNAND(dev,chunkInNAND - dev->chunkOffset,data,(yaffs_Spare*)&nspare); memcpy (spare, &nspare, sizeof(yaffs_Spare)); if(data && doErrorCorrection) { if(nspare.eccres1>0) { - T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset)); } else if(nspare.eccres1<0) { - T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND - dev->chunkOffset)); } if(nspare.eccres2>0) { - T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset)); } else if(nspare.eccres2<0) { - T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND)); + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND - dev->chunkOffset)); } if(nspare.eccres1 || nspare.eccres2) @@ -323,7 +323,7 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND // 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); + dev->readChunkFromNAND(dev,chunkInNAND - dev->chunkOffset,data,(yaffs_Spare *)spare); if(!init) { @@ -344,7 +344,7 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,int blockInNAND) { dev->nBlockErasures++; - return dev->eraseBlockInNAND(dev,blockInNAND); + return dev->eraseBlockInNAND(dev,blockInNAND - dev->blockOffset); } int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev) @@ -2054,11 +2054,11 @@ static int yaffs_FindDirtiestBlock(yaffs_Device *dev,int aggressive) pagesInUse = (aggressive)? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1; if(aggressive) { - iterations = dev->endBlock - dev->startBlock + 1; + iterations = dev->internalEndBlock - dev->internalStartBlock + 1; } else { - iterations = dev->endBlock - dev->startBlock + 1; + iterations = dev->internalEndBlock - dev->internalStartBlock + 1; iterations = iterations / 16; if(iterations > 200) { @@ -2069,12 +2069,12 @@ static int yaffs_FindDirtiestBlock(yaffs_Device *dev,int aggressive) for(i = 0; i <= iterations && pagesInUse > 0 ; i++) { b++; - if ( b < dev->startBlock || b > dev->endBlock) + if ( b < dev->internalStartBlock || b > dev->internalEndBlock) { - b = dev->startBlock; + b = dev->internalStartBlock; } - if(b < dev->startBlock || b > dev->endBlock) + if(b < dev->internalStartBlock || b > dev->internalEndBlock) { T(YAFFS_TRACE_ERROR,(TSTR("**>> Block %d is not valid" TENDSTR),b)); YBUG(); @@ -2151,12 +2151,12 @@ static int yaffs_FindBlockForAllocation(yaffs_Device *dev) // Find an empty block. - for(i = dev->startBlock; i <= dev->endBlock; i++) + for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) { dev->allocationBlockFinder++; - if(dev->allocationBlockFinder startBlock || dev->allocationBlockFinder> dev->endBlock) + if(dev->allocationBlockFinder internalStartBlock || dev->allocationBlockFinder> dev->internalEndBlock) { - dev->allocationBlockFinder = dev->startBlock; + dev->allocationBlockFinder = dev->internalStartBlock; } bi = yaffs_GetBlockInfo(dev,dev->allocationBlockFinder); @@ -3674,7 +3674,7 @@ int yaffs_ResizeFile(yaffs_Object *in, int newSize) // using yaffs_DeleteChunk chunkId = yaffs_FindAndDeleteChunkInFile(in,i,NULL); - if(chunkId < (dev->startBlock * 32) || chunkId >= ((dev->endBlock+1) * 32)) + if(chunkId < (dev->internalStartBlock * 32) || chunkId >= ((dev->internalEndBlock+1) * 32)) { //T(("Found daft chunkId %d for %d\n",chunkId,i)); } @@ -4068,7 +4068,7 @@ static int yaffs_Scan(yaffs_Device *dev) // Scan all the blocks... - for(blk = dev->startBlock; blk <= dev->endBlock; blk++) + for(blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) { deleted = 0; bi = yaffs_GetBlockInfo(dev,blk); @@ -4700,13 +4700,13 @@ int yaffs_GutsInitialise(yaffs_Device *dev) if( dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK || dev->nChunksPerBlock < 2 || dev->nReservedBlocks < 2 || - dev->startBlock <= 0 || + dev->startBlock < 0 || dev->endBlock <= 0 || dev->endBlock <= (dev->startBlock + dev->nReservedBlocks) ) { //these parameters must be set before stating yaffs - // Other parameters startBlock, + // Other parameters internalStartBlock, return YAFFS_FAIL; } @@ -4725,8 +4725,8 @@ int yaffs_GutsInitialise(yaffs_Device *dev) } dev->isMounted = 1; - - if(dev->startBlock <= 0 || + + if(dev->startBlock < 0 || (dev->endBlock - dev->startBlock) < 10) { T(YAFFS_TRACE_ALWAYS,(TSTR("startBlock %d or endBlock %d invalid\n" TENDSTR), @@ -4734,15 +4734,32 @@ int yaffs_GutsInitialise(yaffs_Device *dev) return YAFFS_FAIL; } - nBlocks = dev->endBlock - dev->startBlock + 1; + + // Do we need to add an offset to use block 0? + + dev->internalStartBlock = dev->startBlock; + dev->internalEndBlock = dev->endBlock; + dev->blockOffset = 0; + dev->chunkOffset = 0; + + if(dev->startBlock == 0) + { + dev->internalStartBlock++; + dev->internalEndBlock++; + dev->blockOffset++; + dev->chunkOffset = dev->nChunksPerBlock; + } + + + nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1; // OK now calculate a few things for the device // Calculate chunkGroupBits. - // We need to find the next power of 2 > than endBlock + // We need to find the next power of 2 > than internalEndBlock - x = dev->nChunksPerBlock * (dev->endBlock+1); + x = dev->nChunksPerBlock * (dev->internalEndBlock+1); for(bits = extraBits = 0; x > 1; bits++) { @@ -4914,7 +4931,7 @@ int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev) struct list_head *i; yaffs_Object *l; - for(nFree = 0, b = dev->startBlock; b <= dev->endBlock; b++) + for(nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock; b++) { blk = yaffs_GetBlockInfo(dev,b); diff --git a/yaffs_guts.h b/yaffs_guts.h index 03f8d0d..3728722 100644 --- a/yaffs_guts.h +++ b/yaffs_guts.h @@ -14,7 +14,7 @@ * * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. * - * $Id: yaffs_guts.h,v 1.19 2005-03-29 22:43:38 charles Exp $ + * $Id: yaffs_guts.h,v 1.20 2005-06-25 03:22:24 charles Exp $ */ #ifndef __YAFFS_GUTS_H__ @@ -398,7 +398,7 @@ struct yaffs_DeviceStruct { // Entry parameters set up way early. Yaffs sets up the rest. int nBytesPerChunk; // Should be a power of 2 >= 512 - int nChunksPerBlock; // does not need to be a power of 2 + int nChunksPerBlock; // does not need to be a power of 2 int startBlock; // Start block we're allowed to use int endBlock; // End block we're allowed to use int nReservedBlocks; // We want this tuneable so that we can reduce @@ -420,6 +420,11 @@ struct yaffs_DeviceStruct int (*initialiseNAND)(struct yaffs_DeviceStruct *dev); // Runtime parameters. Set up by YAFFS. + int internalStartBlock; // Internal version of startBlock + int internalEndBlock; // End block we're allowed to use + int blockOffset; + int chunkOffset; + __u16 chunkGroupBits; // 0 for devices <= 32MB. else log2(nchunks) - 16 __u16 chunkGroupSize; // == 2^^chunkGroupBits -- 2.30.2