Rationalise context and parameter handling
authorcharles <charles>
Thu, 18 Feb 2010 01:18:04 +0000 (01:18 +0000)
committercharles <charles>
Thu, 18 Feb 2010 01:18:04 +0000 (01:18 +0000)
16 files changed:
direct/dtest.c
direct/yaffs_fileem.c
direct/yaffs_fileem2k.c
direct/yaffs_norif1.c
direct/yaffs_ramem2k.c
direct/yaffscfg2k.c
direct/yaffsfs.c
yaffs_checkptrw.c
yaffs_fs.c
yaffs_guts.c
yaffs_guts.h
yaffs_mtdif.c
yaffs_mtdif1.c
yaffs_mtdif2.c
yaffs_nand.c
yaffs_tagscompat.c

index 8b32b7e..af02ff3 100644 (file)
@@ -2258,7 +2258,6 @@ void checkpoint_upgrade_test(const char *mountpt,int nmounts)
        
        printf("Create start condition\n");
        yaffs_StartUp();
-       SetCheckpointReservedBlocks(0);
        yaffs_mount(mountpt);
        yaffs_mkdir(a,0);
        sprintf(b,"%s/zz",a);
@@ -2271,7 +2270,6 @@ void checkpoint_upgrade_test(const char *mountpt,int nmounts)
        printf("Umount/mount attempt full\n");
        yaffs_unmount(mountpt);
        
-       SetCheckpointReservedBlocks(10);
        yaffs_mount(mountpt);
        
        printf("unlink small file\n");
index 6953a68..f78f7c5 100644 (file)
@@ -16,7 +16,7 @@
  * This is only intended as test code to test persistence etc.
  */
 
-const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.6 2010-01-11 04:06:47 charles Exp $";
+const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.7 2010-02-18 01:18:04 charles Exp $";
 
 
 #include "yportenv.h"
@@ -210,8 +210,6 @@ int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
 
 int yflash_InitialiseNAND(yaffs_Device *dev)
 {
-       dev->useNANDECC = 1; // force on useNANDECC which gets faked. 
-                                                // This saves us doing ECC checks.
        
        return YAFFS_OK;
 }
index 3fa8d3b..4f58e98 100644 (file)
@@ -16,7 +16,7 @@
  * This is only intended as test code to test persistence etc.
  */
 
-const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.23 2010-01-11 21:43:18 charles Exp $";
+const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.24 2010-02-18 01:18:04 charles Exp $";
 
 
 #include "yportenv.h"
@@ -185,7 +185,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
        CheckInit();
        
        
-       if(dev->inbandTags){
+       if(dev->param.inbandTags){
                
                yaffs_PackedTags2TagsPart * pt2tp;
                pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
@@ -195,7 +195,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];
                                                        
                lseek(h,pos,SEEK_SET);
-               written = write(h,data,dev->totalBytesPerChunk);
+               written = write(h,data,dev->param.totalBytesPerChunk);
 
                
                if(yaffs_testPartialWrite){
@@ -203,7 +203,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                        exit(1);
                }
                
-               if(written != dev->totalBytesPerChunk) return YAFFS_FAIL;
+               if(written != dev->param.totalBytesPerChunk) return YAFFS_FAIL;
 
 
        }
@@ -252,7 +252,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                
                        lseek(h,pos,SEEK_SET);
 
-                       if( 0 && dev->isYaffs2)
+                       if( 0 && dev->param.isYaffs2)
                        {
                        
                                written = write(h,tags,sizeof(yaffs_ExtendedTags));
@@ -261,7 +261,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                        else
                        {
                                yaffs_PackedTags2 pt;
-                               yaffs_PackTags2(&pt,tags, !dev->noTagsECC);
+                               yaffs_PackTags2(&pt,tags, !dev->param.noTagsECC);
                                __u8 * ptab = (__u8 *)&pt;
 
                                nRead = read(h,localBuffer,sizeof(pt));
@@ -330,7 +330,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                
                        lseek(h,pos,SEEK_SET);
 
-                       if( 0 && dev->isYaffs2)
+                       if( 0 && dev->param.isYaffs2)
                        {
                        
                                written = write(h,tags,sizeof(yaffs_ExtendedTags));
@@ -339,7 +339,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u
                        else
                        {
                                yaffs_PackedTags2 pt;
-                               yaffs_PackTags2(&pt,tags,!dev->noTagsECC);
+                               yaffs_PackTags2(&pt,tags,!dev->param.noTagsECC);
                                __u8 * ptab = (__u8 *)&pt;
 
                                nRead = read(h,localBuffer,sizeof(pt));
@@ -404,7 +404,7 @@ int yflash2_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *d
        
        
        
-       if(dev->inbandTags){
+       if(dev->param.inbandTags){
                /* Got to suck the tags out of the data area */
                if(!data) {
                        localData=1;
@@ -421,11 +421,11 @@ int yflash2_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *d
                
                lseek(h,pos,SEEK_SET);
 
-               nRead = read(h, data,dev->totalBytesPerChunk);
+               nRead = read(h, data,dev->param.totalBytesPerChunk);
 
                yaffs_UnpackTags2TagsPart(tags,pt2tp);
                
-               if(nread != dev->totalBytesPerChunk)
+               if(nread != dev->param.totalBytesPerChunk)
                        retval = YAFFS_FAIL;
                        
                if(localData)
@@ -456,7 +456,7 @@ int yflash2_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *d
                        h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];             
                        lseek(h,pos,SEEK_SET);
 
-                       if(0 && dev->isYaffs2)
+                       if(0 && dev->param.isYaffs2)
                        {
                                nread= read(h,tags,sizeof(yaffs_ExtendedTags));
                                if(nread != sizeof(yaffs_ExtendedTags))
@@ -474,7 +474,7 @@ int yflash2_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *d
                        {
                                yaffs_PackedTags2 pt;
                                nread= read(h,&pt,sizeof(pt));
-                               yaffs_UnpackTags2(tags,&pt, !dev->noTagsECC);
+                               yaffs_UnpackTags2(tags,&pt, !dev->param.noTagsECC);
 #ifdef SIMULATE_FAILURES
                                if((chunkInNAND >> 6) == 100) {
                                        if(fail300 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
@@ -519,7 +519,7 @@ int yflash2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
        
        memset(&pt,0,sizeof(pt));
        h = filedisk.handle[(blockNo / ( BLOCKS_PER_HANDLE))];
-       lseek(h,((blockNo % BLOCKS_PER_HANDLE) * dev->nChunksPerBlock) * PAGE_SIZE + PAGE_DATA_SIZE,SEEK_SET);
+       lseek(h,((blockNo % BLOCKS_PER_HANDLE) * dev->param.nChunksPerBlock) * PAGE_SIZE + PAGE_DATA_SIZE,SEEK_SET);
        written = write(h,&pt,sizeof(pt));
                
        if(written != sizeof(pt)) return YAFFS_FAIL;
@@ -558,8 +558,8 @@ int yflash2_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
                
 
                h = filedisk.handle[(blockNumber / ( BLOCKS_PER_HANDLE))];
-               lseek(h,((blockNumber % BLOCKS_PER_HANDLE) * dev->nChunksPerBlock) * PAGE_SIZE,SEEK_SET);               
-               for(i = 0; i < dev->nChunksPerBlock; i++)
+               lseek(h,((blockNumber % BLOCKS_PER_HANDLE) * dev->param.nChunksPerBlock) * PAGE_SIZE,SEEK_SET);         
+               for(i = 0; i < dev->param.nChunksPerBlock; i++)
                {
                        write(h,pg,PAGE_SIZE);
                }
@@ -587,7 +587,7 @@ int yflash2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_Bl
 
        *sequenceNumber = 0;
        
-       chunkNo = blockNo * dev->nChunksPerBlock;
+       chunkNo = blockNo * dev->param.nChunksPerBlock;
        
        yflash2_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
        if(tags.blockBad)
index 8753e4e..376d330 100644 (file)
@@ -35,7 +35,7 @@
  *   
  */
 
-const char *yaffs_norif1_c_version = "$Id: yaffs_norif1.c,v 1.5 2010-01-11 04:06:47 charles Exp $";
+const char *yaffs_norif1_c_version = "$Id: yaffs_norif1.c,v 1.6 2010-02-18 01:18:04 charles Exp $";
 
 #include "yaffs_norif1.h"
 
@@ -113,8 +113,8 @@ __u32 *Chunk2DataAddr(yaffs_Device *dev,int chunkId)
        unsigned chunkInBlock;
        __u32  addr;
        
-       block = chunkId/dev->nChunksPerBlock;
-       chunkInBlock = chunkId % dev->nChunksPerBlock;
+       block = chunkId/dev->param.nChunksPerBlock;
+       chunkInBlock = chunkId % dev->param.nChunksPerBlock;
        
        addr = (__u32) Block2Addr(dev,block);
        addr += chunkInBlock * DATA_BYTES_PER_CHUNK;
@@ -128,8 +128,8 @@ __u32 *Chunk2SpareAddr(yaffs_Device *dev,int chunkId)
        unsigned chunkInBlock;
        __u32 addr;
        
-       block = chunkId/dev->nChunksPerBlock;
-       chunkInBlock = chunkId % dev->nChunksPerBlock;
+       block = chunkId/dev->param.nChunksPerBlock;
+       chunkInBlock = chunkId % dev->param.nChunksPerBlock;
        
        addr = (__u32) Block2Addr(dev,block);
        addr += SPARE_AREA_OFFSET;
@@ -174,7 +174,7 @@ int ynorif1_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data,
                 ynorif1_FlashWrite32(spareAddr,(__u32 *)&tmpSpare,sizeof(yaffs_Spare)/4);
 
                 /* Write the data */            
-                ynorif1_FlashWrite32(dataAddr,(__u32 *)data,dev->totalBytesPerChunk / 4);
+                ynorif1_FlashWrite32(dataAddr,(__u32 *)data,dev->param.totalBytesPerChunk / 4);
                 
                 
                 memcpy(&tmpSpare,spare,sizeof(yaffs_Spare));
@@ -213,7 +213,7 @@ int ynorif1_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaf
        
        if(data)
        {
-               ynorif1_FlashRead32(dataAddr,(__u32 *)data,dev->totalBytesPerChunk / 4);
+               ynorif1_FlashRead32(dataAddr,(__u32 *)data,dev->param.totalBytesPerChunk / 4);
        }
        
         if(spare)
@@ -291,7 +291,7 @@ int ynorif1_InitialiseNAND(yaffs_Device *dev)
        
        ynorif1_FlashInit();
        /* Go through the blocks formatting them if they are not formatted */
-       for(i = dev->startBlock; i <= dev->endBlock; i++){
+       for(i = dev->param.startBlock; i <= dev->param.endBlock; i++){
                if(!ynorif1_IsBlockFormatted(dev,i)){
                        ynorif1_FormatBlock(dev,i);
                }
index 7d8f765..c623e39 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 
-const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.7 2010-01-11 21:43:18 charles Exp $";
+const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.8 2010-02-18 01:18:04 charles Exp $";
 
 #ifndef __KERNEL__
 #define CONFIG_YAFFS_RAM_ENABLED
@@ -221,7 +221,7 @@ int nandemul2k_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const
        {
                x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE];
                
-               yaffs_PackTags2((yaffs_PackedTags2 *)x,tags, !dev->noTagsECC);
+               yaffs_PackTags2((yaffs_PackedTags2 *)x,tags, !dev->param.noTagsECC);
                        
        }
        
@@ -257,7 +257,7 @@ int nandemul2k_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8
        {
                x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE];
                
-               yaffs_UnpackTags2(tags,(yaffs_PackedTags2 *)x, !dev->noTagsECC);
+               yaffs_UnpackTags2(tags,(yaffs_PackedTags2 *)x, !dev->param.noTagsECC);
        }
 
        return YAFFS_OK;
@@ -335,7 +335,7 @@ int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs
 
        *sequenceNumber = 0;
        
-       chunkNo = blockNo * dev->nChunksPerBlock;
+       chunkNo = blockNo * dev->param.nChunksPerBlock;
        
        nandemul2k_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
        if(tags.blockBad)
index 3118fa0..7731ade 100644 (file)
@@ -136,34 +136,34 @@ int yaffs_StartUp(void)
        // Set up devices
        // /ram1   ram, yaffs1
        memset(&ram1Dev,0,sizeof(ram1Dev));
-       ram1Dev.totalBytesPerChunk = 512;
-       ram1Dev.nChunksPerBlock = 32;
-       ram1Dev.nReservedBlocks = 2; // Set this smaller for RAM
-       ram1Dev.startBlock = 0; // Can use block 0
-       ram1Dev.endBlock = 127; // Last block in 2MB.   
-       //ram1Dev.useNANDECC = 1;
-       ram1Dev.nShortOpCaches = 0;     // Disable caching on this device.
-       ram1Dev.genericDevice = (void *) 0;     // Used to identify the device in fstat.
-       ram1Dev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
-       ram1Dev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
-       ram1Dev.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
-       ram1Dev.initialiseNAND = yramdisk_InitialiseNAND;
+       ram1Dev.param.totalBytesPerChunk = 512;
+       ram1Dev.param.nChunksPerBlock = 32;
+       ram1Dev.param.nReservedBlocks = 2; // Set this smaller for RAM
+       ram1Dev.param.startBlock = 0; // Can use block 0
+       ram1Dev.param.endBlock = 127; // Last block in 2MB.     
+       //ram1Dev.param.useNANDECC = 1;
+       ram1Dev.param.nShortOpCaches = 0;       // Disable caching on this device.
+       ram1Dev.context = (void *) 0;   // Used to identify the device in fstat.
+       ram1Dev.param.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND;
+       ram1Dev.param.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND;
+       ram1Dev.param.eraseBlockInNAND = yramdisk_EraseBlockInNAND;
+       ram1Dev.param.initialiseNAND = yramdisk_InitialiseNAND;
 
        // /M18-1 yaffs1 on M18 nor sim
        memset(&m18_1Dev,0,sizeof(m18_1Dev));
-       m18_1Dev.totalBytesPerChunk = 1024;
-       m18_1Dev.nChunksPerBlock =248;
-       m18_1Dev.nReservedBlocks = 2;
-       m18_1Dev.startBlock = 0; // Can use block 0
-       m18_1Dev.endBlock = 31; // Last block
-       m18_1Dev.useNANDECC = 0; // use YAFFS's ECC
-       m18_1Dev.nShortOpCaches = 10; // Use caches
-       m18_1Dev.genericDevice = (void *) 1;    // Used to identify the device in fstat.
-       m18_1Dev.writeChunkToNAND = ynorif1_WriteChunkToNAND;
-       m18_1Dev.readChunkFromNAND = ynorif1_ReadChunkFromNAND;
-       m18_1Dev.eraseBlockInNAND = ynorif1_EraseBlockInNAND;
-       m18_1Dev.initialiseNAND = ynorif1_InitialiseNAND;
-       m18_1Dev.deinitialiseNAND = ynorif1_DeinitialiseNAND;
+       m18_1Dev.param.totalBytesPerChunk = 1024;
+       m18_1Dev.param.nChunksPerBlock =248;
+       m18_1Dev.param.nReservedBlocks = 2;
+       m18_1Dev.param.startBlock = 0; // Can use block 0
+       m18_1Dev.param.endBlock = 31; // Last block
+       m18_1Dev.param.useNANDECC = 0; // use YAFFS's ECC
+       m18_1Dev.param.nShortOpCaches = 10; // Use caches
+       m18_1Dev.context = (void *) 1;  // Used to identify the device in fstat.
+       m18_1Dev.param.writeChunkToNAND = ynorif1_WriteChunkToNAND;
+       m18_1Dev.param.readChunkFromNAND = ynorif1_ReadChunkFromNAND;
+       m18_1Dev.param.eraseBlockInNAND = ynorif1_EraseBlockInNAND;
+       m18_1Dev.param.initialiseNAND = ynorif1_InitialiseNAND;
+       m18_1Dev.param.deinitialiseNAND = ynorif1_DeinitialiseNAND;
 
 
        // /yaffs2 
@@ -173,22 +173,23 @@ int yaffs_StartUp(void)
        //
        memset(&flashDev,0,sizeof(flashDev));
 
-       flashDev.totalBytesPerChunk = 2048;
-       flashDev.nChunksPerBlock = 64;
-       flashDev.nReservedBlocks = 5;
-       flashDev.inbandTags = 0;
-       flashDev.startBlock = 0;
-       flashDev.endBlock = yflash2_GetNumberOfBlocks()-1;
-       flashDev.isYaffs2 = 1;
-       flashDev.wideTnodesDisabled=0;
-       flashDev.nShortOpCaches = 10; // Use caches
-       flashDev.genericDevice = (void *) 2;    // Used to identify the device in fstat.
-       flashDev.writeChunkWithTagsToNAND = yflash2_WriteChunkWithTagsToNAND;
-       flashDev.readChunkWithTagsFromNAND = yflash2_ReadChunkWithTagsFromNAND;
-       flashDev.eraseBlockInNAND = yflash2_EraseBlockInNAND;
-       flashDev.initialiseNAND = yflash2_InitialiseNAND;
-       flashDev.markNANDBlockBad = yflash2_MarkNANDBlockBad;
-       flashDev.queryNANDBlock = yflash2_QueryNANDBlock;
+       flashDev.param.totalBytesPerChunk = 2048;
+       flashDev.param.nChunksPerBlock = 64;
+       flashDev.param.nReservedBlocks = 5;
+       flashDev.param.inbandTags = 0;
+       flashDev.param.startBlock = 0;
+       flashDev.param.endBlock = yflash2_GetNumberOfBlocks()-1;
+       flashDev.param.isYaffs2 = 1;
+       flashDev.param.useNANDECC=1;
+       flashDev.param.wideTnodesDisabled=0;
+       flashDev.param.nShortOpCaches = 10; // Use caches
+       flashDev.context = (void *) 2;  // Used to identify the device in fstat.
+       flashDev.param.writeChunkWithTagsToNAND = yflash2_WriteChunkWithTagsToNAND;
+       flashDev.param.readChunkWithTagsFromNAND = yflash2_ReadChunkWithTagsFromNAND;
+       flashDev.param.eraseBlockInNAND = yflash2_EraseBlockInNAND;
+       flashDev.param.initialiseNAND = yflash2_InitialiseNAND;
+       flashDev.param.markNANDBlockBad = yflash2_MarkNANDBlockBad;
+       flashDev.param.queryNANDBlock = yflash2_QueryNANDBlock;
 
 
        yaffs_initialise(yaffsfs_config);
@@ -198,8 +199,3 @@ int yaffs_StartUp(void)
 
 
 
-void SetCheckpointReservedBlocks(int n)
-{
-//     flashDev.nCheckpointReservedBlocks = n;
-}
-
index c20c738..f7dc552 100644 (file)
@@ -31,7 +31,7 @@
 #define YAFFSFS_RW_SIZE  (1<<YAFFSFS_RW_SHIFT)
 
 
-const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.33 2010-02-16 23:24:57 charles Exp $";
+const char *yaffsfs_c_version="$Id: yaffsfs.c,v 1.34 2010-02-18 01:18:05 charles Exp $";
 
 // configurationList is the list of devices that are supported
 static yaffsfs_DeviceConfiguration *yaffsfs_configurationList;
@@ -1076,7 +1076,7 @@ static int yaffsfs_DoStat(yaffs_Object *obj,struct yaffs_stat *buf)
                obj = yaffs_GetEquivalentObject(obj);
 
        if(obj && buf){
-               buf->st_dev = (int)obj->myDev->genericDevice;
+               buf->st_dev = (int)obj->myDev->context;
                buf->st_ino = obj->objectId;
                buf->st_mode = obj->yst_mode & ~S_IFMT; // clear out file type bits
 
@@ -1556,8 +1556,8 @@ loff_t yaffs_totalspace(const YCHAR *path)
        yaffsfs_Lock();
        dev = yaffsfs_FindDevice(path,&dummy);
        if(dev  && dev->isMounted){
-               retVal = (dev->endBlock - dev->startBlock + 1) - dev->nReservedBlocks;
-               retVal *= dev->nChunksPerBlock;
+               retVal = (dev->param.endBlock - dev->param.startBlock + 1) - dev->param.nReservedBlocks;
+               retVal *= dev->param.nChunksPerBlock;
                retVal *= dev->nDataBytesPerChunk;
 
        } else
@@ -1603,7 +1603,7 @@ void yaffs_initialise(yaffsfs_DeviceConfiguration *cfgList)
 
        while(cfg && cfg->prefix && cfg->dev){
                cfg->dev->isMounted = 0;
-               cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback;
+               cfg->dev->param.removeObjectCallback = yaffsfs_RemoveObjectCallback;
                cfg++;
        }
 
index ce44f1e..7ae263c 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 const char *yaffs_checkptrw_c_version =
-       "$Id: yaffs_checkptrw.c,v 1.22 2009-11-03 02:36:30 charles Exp $";
+       "$Id: yaffs_checkptrw.c,v 1.23 2010-02-18 01:18:04 charles Exp $";
 
 
 #include "yaffs_checkptrw.h"
@@ -20,7 +20,7 @@ const char *yaffs_checkptrw_c_version =
 
 static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
 {
-       int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
+       int blocksAvailable = dev->nErasedBlocks - dev->param.nReservedBlocks;
 
        T(YAFFS_TRACE_CHECKPOINT,
                (TSTR("checkpt blocks available = %d" TENDSTR),
@@ -34,7 +34,7 @@ static int yaffs_CheckpointErase(yaffs_Device *dev)
 {
        int i;
 
-       if (!dev->eraseBlockInNAND)
+       if (!dev->param.eraseBlockInNAND)
                return 0;
        T(YAFFS_TRACE_CHECKPOINT, (TSTR("checking blocks %d to %d"TENDSTR),
                dev->internalStartBlock, dev->internalEndBlock));
@@ -46,12 +46,12 @@ static int yaffs_CheckpointErase(yaffs_Device *dev)
 
                        dev->nBlockErasures++;
 
-                       if (dev->eraseBlockInNAND(dev, i - dev->blockOffset /* realign */)) {
+                       if (dev->param.eraseBlockInNAND(dev, i - dev->blockOffset /* realign */)) {
                                bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
                                dev->nErasedBlocks++;
-                               dev->nFreeChunks += dev->nChunksPerBlock;
+                               dev->nFreeChunks += dev->param.nChunksPerBlock;
                        } else {
-                               dev->markNANDBlockBad(dev, i);
+                               dev->param.markNANDBlockBad(dev, i);
                                bi->blockState = YAFFS_BLOCK_STATE_DEAD;
                        }
                }
@@ -66,10 +66,10 @@ static int yaffs_CheckpointErase(yaffs_Device *dev)
 static void yaffs_CheckpointFindNextErasedBlock(yaffs_Device *dev)
 {
        int  i;
-       int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
+       int blocksAvailable = dev->nErasedBlocks - dev->param.nReservedBlocks;
        T(YAFFS_TRACE_CHECKPOINT,
                (TSTR("allocating checkpt block: erased %d reserved %d avail %d next %d "TENDSTR),
-               dev->nErasedBlocks, dev->nReservedBlocks, blocksAvailable, dev->checkpointNextBlock));
+               dev->nErasedBlocks, dev->param.nReservedBlocks, blocksAvailable, dev->checkpointNextBlock));
 
        if (dev->checkpointNextBlock >= 0 &&
                        dev->checkpointNextBlock <= dev->internalEndBlock &&
@@ -101,10 +101,10 @@ static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev)
 
        if (dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
                for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
-                       int chunk = i * dev->nChunksPerBlock;
+                       int chunk = i * dev->param.nChunksPerBlock;
                        int realignedChunk = chunk - dev->chunkOffset;
 
-                       dev->readChunkWithTagsFromNAND(dev, realignedChunk,
+                       dev->param.readChunkWithTagsFromNAND(dev, realignedChunk,
                                        NULL, &tags);
                        T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
                                i, tags.objectId, tags.sequenceNumber, tags.eccResult));
@@ -134,17 +134,17 @@ int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
        dev->checkpointOpenForWrite = forWriting;
 
        /* Got the functions we need? */
-       if (!dev->writeChunkWithTagsToNAND ||
-                       !dev->readChunkWithTagsFromNAND ||
-                       !dev->eraseBlockInNAND ||
-                       !dev->markNANDBlockBad)
+       if (!dev->param.writeChunkWithTagsToNAND ||
+               !dev->param.readChunkWithTagsFromNAND ||
+               !dev->param.eraseBlockInNAND ||
+               !dev->param.markNANDBlockBad)
                return 0;
 
        if (forWriting && !yaffs_CheckpointSpaceOk(dev))
                return 0;
 
        if (!dev->checkpointBuffer)
-               dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
+               dev->checkpointBuffer = YMALLOC_DMA(dev->param.totalBytesPerChunk);
        if (!dev->checkpointBuffer)
                return 0;
 
@@ -217,7 +217,7 @@ static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
                dev->blocksInCheckpoint++;
        }
 
-       chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;
+       chunk = dev->checkpointCurrentBlock * dev->param.nChunksPerBlock + dev->checkpointCurrentChunk;
 
 
        T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
@@ -227,12 +227,12 @@ static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
 
        dev->nPageWrites++;
 
-       dev->writeChunkWithTagsToNAND(dev, realignedChunk,
+       dev->param.writeChunkWithTagsToNAND(dev, realignedChunk,
                        dev->checkpointBuffer, &tags);
        dev->checkpointByteOffset = 0;
        dev->checkpointPageSequence++;
        dev->checkpointCurrentChunk++;
-       if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock) {
+       if (dev->checkpointCurrentChunk >= dev->param.nChunksPerBlock) {
                dev->checkpointCurrentChunk = 0;
                dev->checkpointCurrentBlock = -1;
        }
@@ -310,7 +310,7 @@ int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
                                ok = 0;
                        else {
                                chunk = dev->checkpointCurrentBlock *
-                                       dev->nChunksPerBlock +
+                                       dev->param.nChunksPerBlock +
                                        dev->checkpointCurrentChunk;
 
                                realignedChunk = chunk - dev->chunkOffset;
@@ -319,7 +319,7 @@ int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
 
                                /* read in the next chunk */
                                /* printf("read checkpoint page %d\n",dev->checkpointPage); */
-                               dev->readChunkWithTagsFromNAND(dev,
+                               dev->param.readChunkWithTagsFromNAND(dev,
                                                realignedChunk,
                                                dev->checkpointBuffer,
                                                &tags);
@@ -333,7 +333,7 @@ int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
                                dev->checkpointPageSequence++;
                                dev->checkpointCurrentChunk++;
 
-                               if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
+                               if (dev->checkpointCurrentChunk >= dev->param.nChunksPerBlock)
                                        dev->checkpointCurrentBlock = -1;
                        }
                }
@@ -375,7 +375,7 @@ int yaffs_CheckpointClose(yaffs_Device *dev)
                dev->checkpointBlockList = NULL;
        }
 
-       dev->nFreeChunks -= dev->blocksInCheckpoint * dev->nChunksPerBlock;
+       dev->nFreeChunks -= dev->blocksInCheckpoint * dev->param.nChunksPerBlock;
        dev->nErasedBlocks -= dev->blocksInCheckpoint;
 
 
index 8034a06..2e09f5c 100644 (file)
@@ -32,7 +32,7 @@
  */
 
 const char *yaffs_fs_c_version =
-    "$Id: yaffs_fs.c,v 1.93 2010-02-10 03:54:08 charles Exp $";
+    "$Id: yaffs_fs.c,v 1.94 2010-02-18 01:18:04 charles Exp $";
 extern const char *yaffs_guts_c_version;
 
 #include <linux/version.h>
@@ -117,6 +117,8 @@ static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
 #include "yaffs_trace.h"
 #include "yaffs_guts.h"
 
+#include "yaffs_linux.h"
+
 #include <linux/mtd/mtd.h>
 #include "yaffs_mtdif.h"
 #include "yaffs_mtdif1.h"
@@ -379,18 +381,18 @@ static const struct super_operations yaffs_super_ops = {
        .sync_fs = yaffs_sync_fs,
        .write_super = yaffs_write_super,
 };
-
+                                                                                                                       
 static void yaffs_GrossLock(yaffs_Device *dev)
 {
        T(LOCK_TRACE && YAFFS_TRACE_OS, ("yaffs locking %p\n", current));
-       down(&dev->grossLock);
+       down(&(yaffs_DeviceToContext(dev)->grossLock));
        T(LOCK_TRACE && YAFFS_TRACE_OS, ("yaffs locked %p\n", current));
 }
 
 static void yaffs_GrossUnlock(yaffs_Device *dev)
 {
        T(LOCK_TRACE && YAFFS_TRACE_OS, ("yaffs unlocking %p\n", current));
-       up(&dev->grossLock);
+       up(&(yaffs_DeviceToContext(dev)->grossLock));
 }
 
 
@@ -440,7 +442,7 @@ static struct yaffs_SearchContext * yaffs_NewSearch(yaffs_Object *dir)
                                 dir->variant.directoryVariant.children.next,
                                yaffs_Object,siblings);
                YINIT_LIST_HEAD(&sc->others);
-               ylist_add(&sc->others,&dev->searchContexts);
+               ylist_add(&sc->others,&(yaffs_DeviceToContext(dev)->searchContexts));
        }
        return sc;
 }
@@ -489,7 +491,7 @@ static void yaffs_RemoveObjectCallback(yaffs_Object *obj)
 
         struct ylist_head *i;
         struct yaffs_SearchContext *sc;
-        struct ylist_head *search_contexts = &obj->myDev->searchContexts;
+        struct ylist_head *search_contexts = &(yaffs_DeviceToContext(obj->myDev)->searchContexts);
 
 
         /* Iterate through the directory search contexts.
@@ -1734,8 +1736,8 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
                uint64_t bytesInDev;
                uint64_t bytesFree;
 
-               bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock + 1))) *
-                       ((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk));
+               bytesInDev = ((uint64_t)((dev->param.endBlock - dev->param.startBlock + 1))) *
+                       ((uint64_t)(dev->param.nChunksPerBlock * dev->nDataBytesPerChunk));
 
                do_div(bytesInDev, sb->s_blocksize); /* bytesInDev becomes the number of blocks */
                buf->f_blocks = bytesInDev;
@@ -1750,16 +1752,16 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
        } else if (sb->s_blocksize > dev->nDataBytesPerChunk) {
 
                buf->f_blocks =
-                       (dev->endBlock - dev->startBlock + 1) *
-                       dev->nChunksPerBlock /
+                       (dev->param.endBlock - dev->param.startBlock + 1) *
+                       dev->param.nChunksPerBlock /
                        (sb->s_blocksize / dev->nDataBytesPerChunk);
                buf->f_bfree =
                        yaffs_GetNumberOfFreeChunks(dev) /
                        (sb->s_blocksize / dev->nDataBytesPerChunk);
        } else {
                buf->f_blocks =
-                       (dev->endBlock - dev->startBlock + 1) *
-                       dev->nChunksPerBlock *
+                       (dev->param.endBlock - dev->param.startBlock + 1) *
+                       dev->param.nChunksPerBlock *
                        (dev->nDataBytesPerChunk / sb->s_blocksize);
 
                buf->f_bfree =
@@ -1904,7 +1906,7 @@ static void yaffs_read_inode(struct inode *inode)
 
 #endif
 
-static YLIST_HEAD(yaffs_dev_list);
+static YLIST_HEAD(yaffs_context_list);
 
 #if 0 /* not used */
 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
@@ -1948,19 +1950,19 @@ static void yaffs_put_super(struct super_block *sb)
 
        yaffs_CheckpointSave(dev);
 
-       if (dev->putSuperFunc)
-               dev->putSuperFunc(sb);
+       if (yaffs_DeviceToContext(dev)->putSuperFunc)
+               yaffs_DeviceToContext(dev)->putSuperFunc(sb);
 
        yaffs_Deinitialise(dev);
 
        yaffs_GrossUnlock(dev);
 
        /* we assume this is protected by lock_kernel() in mount/umount */
-       ylist_del(&dev->devList);
+       ylist_del_init(&(yaffs_DeviceToContext(dev)->contextList));
 
-       if (dev->spareBuffer) {
-               YFREE(dev->spareBuffer);
-               dev->spareBuffer = NULL;
+       if (yaffs_DeviceToContext(dev)->spareBuffer) {
+               YFREE(yaffs_DeviceToContext(dev)->spareBuffer);
+               yaffs_DeviceToContext(dev)->spareBuffer = NULL;
        }
 
        kfree(dev);
@@ -1969,7 +1971,7 @@ static void yaffs_put_super(struct super_block *sb)
 
 static void yaffs_MTDPutSuper(struct super_block *sb)
 {
-       struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
+       struct mtd_info *mtd = yaffs_DeviceToContext(yaffs_SuperToDevice(sb))->mtd;
 
        if (mtd->sync)
                mtd->sync(mtd);
@@ -1978,9 +1980,9 @@ static void yaffs_MTDPutSuper(struct super_block *sb)
 }
 
 
-static void yaffs_MarkSuperBlockDirty(void *vsb)
+static void yaffs_MarkSuperBlockDirty(yaffs_Device *dev)
 {
-       struct super_block *sb = (struct super_block *)vsb;
+       struct super_block *sb = yaffs_DeviceToContext(dev)->superBlock;
 
        T(YAFFS_TRACE_OS, ("yaffs_MarkSuperBlockDirty() sb = %p\n", sb));
        if (sb)
@@ -2075,6 +2077,8 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
        struct mtd_info *mtd;
        int err;
        char *data_str = (char *)data;
+       struct yaffs_LinuxContext *context = NULL;
+       yaffs_DeviceParam *param;
 
        yaffs_options options;
 
@@ -2231,11 +2235,18 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
         * Set the yaffs_Device up for mtd
         */
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-       sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
-#else
-       sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
-#endif
+       dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
+       context = kmalloc(sizeof(struct yaffs_LinuxContext),GFP_KERNEL);
+       
+       if(!dev || !context ){
+               if(dev)
+                       kfree(dev);
+               if(context)
+                       kfree(context);
+               dev = NULL;
+               context = NULL;
+       }
+
        if (!dev) {
                /* Deep shit could not allocate device structure */
                T(YAFFS_TRACE_ALWAYS,
@@ -2243,106 +2254,122 @@ static struct super_block *yaffs_internal_read_super(int yaffsVersion,
                   "yaffs_Device. \n"));
                return NULL;
        }
-
        memset(dev, 0, sizeof(yaffs_Device));
-       dev->genericDevice = mtd;
-       dev->name = mtd->name;
+       param = &(dev->param);
+
+       memset(context,0,sizeof(struct yaffs_LinuxContext));
+       dev->context = context;
+       YINIT_LIST_HEAD(&(context->contextList));
+       context->dev = dev;
+       context->superBlock = sb;
+
+       
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
+       sb->s_fs_info = dev;
+#else
+       sb->u.generic_sbp = dev;
+#endif
+       
+       yaffs_DeviceToContext(dev)->mtd = mtd;
+       param->name = mtd->name;
 
        /* Set up the memory size parameters.... */
 
        nBlocks = YCALCBLOCKS(mtd->size, (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));
 
-       dev->startBlock = 0;
-       dev->endBlock = nBlocks - 1;
-       dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
-       dev->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
-       dev->nReservedBlocks = 5;
-       dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
-       dev->inbandTags = options.inband_tags;
+       param->startBlock = 0;
+       param->endBlock = nBlocks - 1;
+       param->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
+       param->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
+       param->nReservedBlocks = 5;
+       param->nShortOpCaches = (options.no_cache) ? 0 : 10;
+       param->inbandTags = options.inband_tags;
 
 #ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
-       dev->disableLazyLoad = 1;
+       param->disableLazyLoad = 1;
 #endif
        if(options.lazy_loading_overridden)
-               dev->disableLazyLoad = !options.lazy_loading_enabled;
+               param->disableLazyLoad = !options.lazy_loading_enabled;
 
 #ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
-       dev->noTagsECC = 1;
+       param->noTagsECC = 1;
 #endif
        if(options.tags_ecc_overridden)
-               dev->noTagsECC = !options.tags_ecc_on;
+               param->noTagsECC = !options.tags_ecc_on;
 
 #ifdef CONFIG_YAFFS_EMPTY_LOST_AND_FOUND
        dev->emptyLostAndFound = 1;
 #endif
        if(options.empty_lost_and_found_overridden)
-               dev->emptyLostAndFound = options.empty_lost_and_found;
+               param->emptyLostAndFound = options.empty_lost_and_found;
 
        /* ... and the functions. */
        if (yaffsVersion == 2) {
-               dev->writeChunkWithTagsToNAND =
+               param->writeChunkWithTagsToNAND =
                    nandmtd2_WriteChunkWithTagsToNAND;
-               dev->readChunkWithTagsFromNAND =
+               param->readChunkWithTagsFromNAND =
                    nandmtd2_ReadChunkWithTagsFromNAND;
-               dev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
-               dev->queryNANDBlock = nandmtd2_QueryNANDBlock;
-               dev->spareBuffer = YMALLOC(mtd->oobsize);
-               dev->isYaffs2 = 1;
+               param->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
+               param->queryNANDBlock = nandmtd2_QueryNANDBlock;
+               yaffs_DeviceToContext(dev)->spareBuffer = YMALLOC(mtd->oobsize);
+               param->isYaffs2 = 1;
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-               dev->totalBytesPerChunk = mtd->writesize;
-               dev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
+               param->totalBytesPerChunk = mtd->writesize;
+               param->nChunksPerBlock = mtd->erasesize / mtd->writesize;
 #else
-               dev->totalBytesPerChunk = mtd->oobblock;
-               dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
+               param->totalBytesPerChunk = mtd->oobblock;
+               param->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
 #endif
                nBlocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
 
-               dev->startBlock = 0;
-               dev->endBlock = nBlocks - 1;
+               param->startBlock = 0;
+               param->endBlock = nBlocks - 1;
        } else {
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
                /* use the MTD interface in yaffs_mtdif1.c */
-               dev->writeChunkWithTagsToNAND =
+               param->writeChunkWithTagsToNAND =
                        nandmtd1_WriteChunkWithTagsToNAND;
-               dev->readChunkWithTagsFromNAND =
+               param->readChunkWithTagsFromNAND =
                        nandmtd1_ReadChunkWithTagsFromNAND;
-               dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad;
-               dev->queryNANDBlock = nandmtd1_QueryNANDBlock;
+               param->markNANDBlockBad = nandmtd1_MarkNANDBlockBad;
+               param->queryNANDBlock = nandmtd1_QueryNANDBlock;
 #else
-               dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
-               dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
+               param->writeChunkToNAND = nandmtd_WriteChunkToNAND;
+               param->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
 #endif
-               dev->isYaffs2 = 0;
+               param->isYaffs2 = 0;
        }
        /* ... and common functions */
-       dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
-       dev->initialiseNAND = nandmtd_InitialiseNAND;
+       param->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
+       param->initialiseNAND = nandmtd_InitialiseNAND;
 
-       dev->putSuperFunc = yaffs_MTDPutSuper;
+       yaffs_DeviceToContext(dev)->putSuperFunc = yaffs_MTDPutSuper;
 
-       dev->superBlock = (void *)sb;
-       dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;
+       param->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;
 
+       yaffs_DeviceToContext(dev)->superBlock= sb;
+       
 
 #ifndef CONFIG_YAFFS_DOES_ECC
-       dev->useNANDECC = 1;
+       param->useNANDECC = 1;
 #endif
 
 #ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES
-       dev->wideTnodesDisabled = 1;
+       param->wideTnodesDisabled = 1;
 #endif
 
-       dev->skipCheckpointRead = options.skip_checkpoint_read;
-       dev->skipCheckpointWrite = options.skip_checkpoint_write;
+       param->skipCheckpointRead = options.skip_checkpoint_read;
+       param->skipCheckpointWrite = options.skip_checkpoint_write;
 
        /* we assume this is protected by lock_kernel() in mount/umount */
-       ylist_add_tail(&dev->devList, &yaffs_dev_list);
+       ylist_add_tail(&(yaffs_DeviceToContext(dev)->contextList), &yaffs_context_list);
 
         /* Directory search handling...*/
-        YINIT_LIST_HEAD(&dev->searchContexts);
-        dev->removeObjectCallback = yaffs_RemoveObjectCallback;
+        YINIT_LIST_HEAD(&(yaffs_DeviceToContext(dev)->searchContexts));
+        param->removeObjectCallback = yaffs_RemoveObjectCallback;
 
-       init_MUTEX(&dev->grossLock);
+       init_MUTEX(&(yaffs_DeviceToContext(dev)->grossLock));
 
        yaffs_GrossLock(dev);
 
@@ -2484,14 +2511,14 @@ static struct proc_dir_entry *my_proc_entry;
 
 static char *yaffs_dump_dev_part0(char *buf, yaffs_Device * dev)
 {
-       buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock);
-       buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock);
-       buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->totalBytesPerChunk);
+       buf += sprintf(buf, "startBlock......... %d\n", dev->param.startBlock);
+       buf += sprintf(buf, "endBlock........... %d\n", dev->param.endBlock);
+       buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->param.totalBytesPerChunk);
        buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk);
        buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits);
        buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);
        buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks);
-       buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks);
+       buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->param.nReservedBlocks);
        buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);
        buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated);
        buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes);
@@ -2506,7 +2533,7 @@ static char *yaffs_dump_dev_part0(char *buf, yaffs_Device * dev)
        buf += sprintf(buf, "passiveGCs......... %d\n",
                    dev->passiveGarbageCollections);
        buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites);
-       buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches);
+       buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->param.nShortOpCaches);
        buf += sprintf(buf, "nRetireBlocks...... %d\n", dev->nRetiredBlocks);
        buf += sprintf(buf, "eccFixed........... %d\n", dev->eccFixed);
        buf += sprintf(buf, "eccUnfixed......... %d\n", dev->eccUnfixed);
@@ -2524,12 +2551,12 @@ static char *yaffs_dump_dev_part0(char *buf, yaffs_Device * dev)
 
 static char *yaffs_dump_dev_part1(char *buf, yaffs_Device * dev)
 {
-       buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);
-       buf += sprintf(buf, "noTagsECC.......... %d\n", dev->noTagsECC);
-       buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);
-       buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);
-       buf += sprintf(buf, "emptyLostAndFound.. %d\n", dev->emptyLostAndFound);
-       buf += sprintf(buf, "disableLazyLoad.... %d\n", dev->disableLazyLoad);
+       buf += sprintf(buf, "useNANDECC......... %d\n", dev->param.useNANDECC);
+       buf += sprintf(buf, "noTagsECC.......... %d\n", dev->param.noTagsECC);
+       buf += sprintf(buf, "isYaffs2........... %d\n", dev->param.isYaffs2);
+       buf += sprintf(buf, "inbandTags......... %d\n", dev->param.inbandTags);
+       buf += sprintf(buf, "emptyLostAndFound.. %d\n", dev->param.emptyLostAndFound);
+       buf += sprintf(buf, "disableLazyLoad.... %d\n", dev->param.disableLazyLoad);
 
        return buf;
 }
@@ -2565,14 +2592,16 @@ static int yaffs_proc_read(char *page,
                lock_kernel();
 
                /* Locate and print the Nth entry.  Order N-squared but N is small. */
-               ylist_for_each(item, &yaffs_dev_list) {
-                       yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList);
+               ylist_for_each(item, &yaffs_context_list) {
+                       struct yaffs_LinuxContext *dc = ylist_entry(item, struct yaffs_LinuxContext, contextList);
+                       yaffs_Device *dev = dc->dev;
+
                        if (n < (step & ~1)) {
                                n+=2;
                                continue;
                        }
                        if((step & 1)==0){
-                               buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->name);
+                               buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->param.name);
                                buf = yaffs_dump_dev_part0(buf, dev);
                        } else
                                buf = yaffs_dump_dev_part1(buf, dev);
index df8efbe..1b0a67f 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 const char *yaffs_guts_c_version =
-    "$Id: yaffs_guts.c,v 1.107 2010-02-17 02:01:25 charles Exp $";
+    "$Id: yaffs_guts.c,v 1.108 2010-02-18 01:18:04 charles Exp $";
 
 #include "yportenv.h"
 #include "yaffs_trace.h"
@@ -210,7 +210,7 @@ static int yaffs_InitialiseTempBuffers(yaffs_Device *dev)
        for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
                dev->tempBuffer[i].line = 0;    /* not in use */
                dev->tempBuffer[i].buffer = buf =
-                   YMALLOC_DMA(dev->totalBytesPerChunk);
+                   YMALLOC_DMA(dev->param.totalBytesPerChunk);
        }
 
        return buf ? YAFFS_OK : YAFFS_FAIL;
@@ -293,7 +293,7 @@ int yaffs_IsManagedTempBuffer(yaffs_Device *dev, const __u8 *buffer)
                        return 1;
        }
 
-       for (i = 0; i < dev->nShortOpCaches; i++) {
+       for (i = 0; i < dev->param.nShortOpCaches; i++) {
                if (dev->srCache[i].data == buffer)
                        return 1;
        }
@@ -327,7 +327,7 @@ static Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk)
 static Y_INLINE void yaffs_VerifyChunkBitId(yaffs_Device *dev, int blk, int chunk)
 {
        if (blk < dev->internalStartBlock || blk > dev->internalEndBlock ||
-                       chunk < 0 || chunk >= dev->nChunksPerBlock) {
+                       chunk < 0 || chunk >= dev->param.nChunksPerBlock) {
                T(YAFFS_TRACE_ERROR,
                (TSTR("**>> yaffs: Chunk Id (%d:%d) invalid"TENDSTR),
                        blk, chunk));
@@ -454,9 +454,9 @@ static void yaffs_VerifyBlock(yaffs_Device *dev, yaffs_BlockInfo *bi, int n)
 
        actuallyUsed = bi->pagesInUse - bi->softDeletions;
 
-       if (bi->pagesInUse < 0 || bi->pagesInUse > dev->nChunksPerBlock ||
-          bi->softDeletions < 0 || bi->softDeletions > dev->nChunksPerBlock ||
-          actuallyUsed < 0 || actuallyUsed > dev->nChunksPerBlock)
+       if (bi->pagesInUse < 0 || bi->pagesInUse > dev->param.nChunksPerBlock ||
+          bi->softDeletions < 0 || bi->softDeletions > dev->param.nChunksPerBlock ||
+          actuallyUsed < 0 || actuallyUsed > dev->param.nChunksPerBlock)
                T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has illegal values pagesInUsed %d softDeletions %d"TENDSTR),
                n, bi->pagesInUse, bi->softDeletions));
 
@@ -470,7 +470,7 @@ static void yaffs_VerifyBlock(yaffs_Device *dev, yaffs_BlockInfo *bi, int n)
        /* Check that the sequence number is valid.
         * Ten million is legal, but is very unlikely
         */
-       if (dev->isYaffs2 &&
+       if (dev->param.isYaffs2 &&
           (bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING || bi->blockState == YAFFS_BLOCK_STATE_FULL) &&
           (bi->sequenceNumber < YAFFS_LOWEST_SEQUENCE_NUMBER || bi->sequenceNumber > 10000000))
                T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has suspect sequence number of %d"TENDSTR),
@@ -762,15 +762,15 @@ static void yaffs_VerifyObject(yaffs_Object *obj)
 
        /* Check sane object header chunk */
 
-       chunkMin = dev->internalStartBlock * dev->nChunksPerBlock;
-       chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1;
+       chunkMin = dev->internalStartBlock * dev->param.nChunksPerBlock;
+       chunkMax = (dev->internalEndBlock+1) * dev->param.nChunksPerBlock - 1;
 
        chunkInRange = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax);
        chunkIdOk = chunkInRange || (obj->hdrChunk == 0);
        chunkValid = chunkInRange &&
                        yaffs_CheckChunkBit(dev,
-                                       obj->hdrChunk / dev->nChunksPerBlock,
-                                       obj->hdrChunk % dev->nChunksPerBlock);
+                                       obj->hdrChunk / dev->param.nChunksPerBlock,
+                                       obj->hdrChunk % dev->param.nChunksPerBlock);
        chunkShouldNotBeDeleted = chunkInRange && !chunkValid;
 
        if (!obj->fake &&
@@ -1067,14 +1067,14 @@ static void yaffs_RetireBlock(yaffs_Device *dev, int blockInNAND)
                                TENDSTR), blockInNAND));
                } else {
                        yaffs_ExtendedTags tags;
-                       int chunkId = blockInNAND * dev->nChunksPerBlock;
+                       int chunkId = blockInNAND * dev->param.nChunksPerBlock;
 
                        __u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
 
                        memset(buffer, 0xff, dev->nDataBytesPerChunk);
                        yaffs_InitialiseTags(&tags);
                        tags.sequenceNumber = YAFFS_SEQUENCE_BAD_BLOCK;
-                       if (dev->writeChunkWithTagsToNAND(dev, chunkId -
+                       if (dev->param.writeChunkWithTagsToNAND(dev, chunkId -
                                dev->chunkOffset, buffer, &tags) != YAFFS_OK)
                                T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Failed to "
                                        TCONT("write bad block marker to block %d")
@@ -1125,7 +1125,7 @@ void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi)
 static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND,
                int erasedOk)
 {
-       int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
+       int blockInNAND = chunkInNAND / dev->param.nChunksPerBlock;
        yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
 
        yaffs_HandleChunkError(dev, bi);
@@ -1598,8 +1598,8 @@ static int yaffs_FindChunkInGroup(yaffs_Device *dev, int theChunk,
        int j;
 
        for (j = 0; theChunk && j < dev->chunkGroupSize; j++) {
-               if (yaffs_CheckChunkBit(dev, theChunk / dev->nChunksPerBlock,
-                               theChunk % dev->nChunksPerBlock)) {
+               if (yaffs_CheckChunkBit(dev, theChunk / dev->param.nChunksPerBlock,
+                               theChunk % dev->param.nChunksPerBlock)) {
                        
                        if(dev->chunkGroupSize == 1)
                                return theChunk;
@@ -1717,7 +1717,7 @@ static void yaffs_SoftDeleteChunk(yaffs_Device *dev, int chunk)
 
        T(YAFFS_TRACE_DELETION, (TSTR("soft delete chunk %d" TENDSTR), chunk));
 
-       theBlock = yaffs_GetBlockInfo(dev, chunk / dev->nChunksPerBlock);
+       theBlock = yaffs_GetBlockInfo(dev, chunk / dev->param.nChunksPerBlock);
        if (theBlock) {
                theBlock->softDeletions++;
                dev->nFreeChunks++;
@@ -2092,7 +2092,6 @@ static void yaffs_FreeObject(yaffs_Object *tn)
        dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
 }
 
-#ifdef __KERNEL__
 
 void yaffs_HandleDeferedFree(yaffs_Object *obj)
 {
@@ -2100,7 +2099,6 @@ void yaffs_HandleDeferedFree(yaffs_Object *obj)
                yaffs_FreeObject(obj);
 }
 
-#endif
 
 static void yaffs_DeinitialiseObjects(yaffs_Device *dev)
 {
@@ -2223,11 +2221,10 @@ yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number)
                if (i) {
                        in = ylist_entry(i, yaffs_Object, hashLink);
                        if (in->objectId == number) {
-#ifdef __KERNEL__
+
                                /* Don't tell the VFS about this one if it is defered free */
                                if (in->deferedFree)
                                        return NULL;
-#endif
 
                                return in;
                        }
@@ -2508,7 +2505,7 @@ static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir,
        }
 
        /* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
-       if (obj->myDev->isYaffs2)
+       if (obj->myDev->param.isYaffs2)
                unlinkOp = (newDir == obj->myDev->unlinkedDir);
        else
                unlinkOp = (newDir == obj->myDev->unlinkedDir
@@ -2634,7 +2631,7 @@ static int yaffs_InitialiseBlocks(yaffs_Device *dev)
 
        if (dev->blockInfo) {
                /* Set up dynamic blockinfo stuff. */
-               dev->chunkBitmapStride = (dev->nChunksPerBlock + 7) / 8; /* round up bytes */
+               dev->chunkBitmapStride = (dev->param.nChunksPerBlock + 7) / 8; /* round up bytes */
                dev->chunkBits = YMALLOC(dev->chunkBitmapStride * nBlocks);
                if (!dev->chunkBits) {
                        dev->chunkBits = YMALLOC_ALT(dev->chunkBitmapStride * nBlocks);
@@ -2678,7 +2675,7 @@ static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device *dev,
        __u32 seq;
        yaffs_BlockInfo *b;
 
-       if (!dev->isYaffs2)
+       if (!dev->param.isYaffs2)
                return 1;       /* disqualification only applies to yaffs2. */
 
        if (!bi->hasShrinkHeader)
@@ -2695,7 +2692,7 @@ static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device *dev,
                        b = yaffs_GetBlockInfo(dev, i);
                        if (b->blockState == YAFFS_BLOCK_STATE_FULL &&
                            (b->pagesInUse - b->softDeletions) <
-                           dev->nChunksPerBlock && b->sequenceNumber < seq) {
+                           dev->param.nChunksPerBlock && b->sequenceNumber < seq) {
                                seq = b->sequenceNumber;
                        }
                }
@@ -2761,7 +2758,7 @@ static int yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
 
        if (!prioritised)
                pagesInUse =
-                       (aggressive) ? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
+                       (aggressive) ? dev->param.nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
 
        if (aggressive)
                iterations =
@@ -2800,7 +2797,7 @@ static int yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
        if (dirtiest > 0) {
                T(YAFFS_TRACE_GC,
                  (TSTR("GC Selected block %d with %d free, prioritised:%d" TENDSTR), dirtiest,
-                  dev->nChunksPerBlock - pagesInUse, prioritised));
+                  dev->param.nChunksPerBlock - pagesInUse, prioritised));
        }
 
        dev->oldestDirtySequence = 0;
@@ -2840,9 +2837,9 @@ static void yaffs_BlockBecameDirty(yaffs_Device *dev, int blockNo)
        if (erasedOk &&
            ((yaffs_traceMask & YAFFS_TRACE_ERASE) || !yaffs_SkipVerification(dev))) {
                int i;
-               for (i = 0; i < dev->nChunksPerBlock; i++) {
+               for (i = 0; i < dev->param.nChunksPerBlock; i++) {
                        if (!yaffs_CheckChunkErased
-                           (dev, blockNo * dev->nChunksPerBlock + i)) {
+                           (dev, blockNo * dev->param.nChunksPerBlock + i)) {
                                T(YAFFS_TRACE_ERROR,
                                  (TSTR
                                   (">>Block %d erasure supposedly OK, but chunk %d not erased"
@@ -2865,7 +2862,7 @@ static void yaffs_BlockBecameDirty(yaffs_Device *dev, int blockNo)
                T(YAFFS_TRACE_ERASE,
                  (TSTR("Erased block %d" TENDSTR), blockNo));
        } else {
-               dev->nFreeChunks -= dev->nChunksPerBlock;       /* We lost a block of free space */
+               dev->nFreeChunks -= dev->param.nChunksPerBlock; /* We lost a block of free space */
 
                yaffs_RetireBlock(dev, blockNo);
                T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
@@ -2926,11 +2923,11 @@ static int yaffs_FindBlockForAllocation(yaffs_Device *dev)
 static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
 {
        if (!dev->nCheckpointBlocksRequired &&
-          dev->isYaffs2) {
+          dev->param.isYaffs2) {
                /* Not a valid value so recalculate */
                int nBytes = 0;
                int nBlocks;
-               int devBlocks = (dev->endBlock - dev->startBlock + 1);
+               int devBlocks = (dev->param.endBlock - dev->param.startBlock + 1);
                int tnodeSize = yaffs_CalcTnodeSize(dev);
 
                nBytes += sizeof(yaffs_CheckpointValidity);
@@ -2944,7 +2941,7 @@ static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
 
                /* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
 
-               nBlocks = (nBytes/(dev->nDataBytesPerChunk * dev->nChunksPerBlock)) + 3;
+               nBlocks = (nBytes/(dev->nDataBytesPerChunk * dev->param.nChunksPerBlock)) + 3;
 
                dev->nCheckpointBlocksRequired = nBlocks;
        }
@@ -2959,10 +2956,10 @@ static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
 static int yaffs_CheckSpaceForAllocation(yaffs_Device *dev)
 {
        int reservedChunks;
-       int reservedBlocks = dev->nReservedBlocks;
+       int reservedBlocks = dev->param.nReservedBlocks;
        int checkpointBlocks;
 
-       if (dev->isYaffs2) {
+       if (dev->param.isYaffs2) {
                checkpointBlocks =  yaffs_CalcCheckpointBlocksRequired(dev) -
                                    dev->blocksInCheckpoint;
                if (checkpointBlocks < 0)
@@ -2971,7 +2968,7 @@ static int yaffs_CheckSpaceForAllocation(yaffs_Device *dev)
                checkpointBlocks = 0;
        }
 
-       reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock);
+       reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->param.nChunksPerBlock);
 
        return (dev->nFreeChunks > reservedChunks);
 }
@@ -2993,7 +2990,7 @@ static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
                return -1;
        }
 
-       if (dev->nErasedBlocks < dev->nReservedBlocks
+       if (dev->nErasedBlocks < dev->param.nReservedBlocks
                        && dev->allocationPage == 0) {
                T(YAFFS_TRACE_ALLOCATE, (TSTR("Allocating reserve" TENDSTR)));
        }
@@ -3002,7 +2999,7 @@ static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
        if (dev->allocationBlock >= 0) {
                bi = yaffs_GetBlockInfo(dev, dev->allocationBlock);
 
-               retVal = (dev->allocationBlock * dev->nChunksPerBlock) +
+               retVal = (dev->allocationBlock * dev->param.nChunksPerBlock) +
                        dev->allocationPage;
                bi->pagesInUse++;
                yaffs_SetChunkBit(dev, dev->allocationBlock,
@@ -3013,7 +3010,7 @@ static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
                dev->nFreeChunks--;
 
                /* If the block is full set the state to full */
-               if (dev->allocationPage >= dev->nChunksPerBlock) {
+               if (dev->allocationPage >= dev->param.nChunksPerBlock) {
                        bi->blockState = YAFFS_BLOCK_STATE_FULL;
                        dev->allocationBlock = -1;
                }
@@ -3034,10 +3031,10 @@ static int yaffs_GetErasedChunks(yaffs_Device *dev)
 {
        int n;
 
-       n = dev->nErasedBlocks * dev->nChunksPerBlock;
+       n = dev->nErasedBlocks * dev->param.nChunksPerBlock;
 
        if (dev->allocationBlock > 0)
-               n += (dev->nChunksPerBlock - dev->allocationPage);
+               n += (dev->param.nChunksPerBlock - dev->allocationPage);
 
        return n;
 
@@ -3119,12 +3116,12 @@ static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
 
                yaffs_VerifyBlock(dev, bi, block);
 
-               maxCopies = (wholeBlock) ? dev->nChunksPerBlock : 10;
-               oldChunk = block * dev->nChunksPerBlock + dev->gcChunk;
+               maxCopies = (wholeBlock) ? dev->param.nChunksPerBlock : 10;
+               oldChunk = block * dev->param.nChunksPerBlock + dev->gcChunk;
 
                for (/* init already done */;
                     retVal == YAFFS_OK &&
-                    dev->gcChunk < dev->nChunksPerBlock &&
+                    dev->gcChunk < dev->param.nChunksPerBlock &&
                     (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) &&
                     maxCopies > 0;
                     dev->gcChunk++, oldChunk++) {
@@ -3345,7 +3342,7 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev)
                if (checkpointBlockAdjust < 0)
                        checkpointBlockAdjust = 0;
 
-               if (dev->nErasedBlocks < (dev->nReservedBlocks + checkpointBlockAdjust + 2)) {
+               if (dev->nErasedBlocks < (dev->param.nReservedBlocks + checkpointBlockAdjust + 2)) {
                        /* We need a block soon...*/
                        aggressive = 1;
                } else {
@@ -3373,13 +3370,13 @@ static int yaffs_CheckGarbageCollection(yaffs_Device *dev)
                        gcOk = yaffs_GarbageCollectBlock(dev, block, aggressive);
                }
 
-               if (dev->nErasedBlocks < (dev->nReservedBlocks) && block > 0) {
+               if (dev->nErasedBlocks < (dev->param.nReservedBlocks) && block > 0) {
                        T(YAFFS_TRACE_GC,
                          (TSTR
                           ("yaffs: GC !!!no reclaim!!! erasedBlocks %d after try %d block %d"
                            TENDSTR), dev->nErasedBlocks, maxTries, block));
                }
-       } while ((dev->nErasedBlocks < dev->nReservedBlocks) &&
+       } while ((dev->nErasedBlocks < dev->param.nReservedBlocks) &&
                 (block > 0) &&
                 (maxTries < 2));
 
@@ -3493,8 +3490,8 @@ static int yaffs_CheckFileSanity(yaffs_Object *in)
                        theChunk = yaffs_GetChunkGroupBase(dev, tn, chunk);
 
                        if (yaffs_CheckChunkBits
-                           (dev, theChunk / dev->nChunksPerBlock,
-                            theChunk % dev->nChunksPerBlock)) {
+                           (dev, theChunk / dev->param.nChunksPerBlock,
+                            theChunk % dev->param.nChunksPerBlock)) {
 
                                yaffs_ReadChunkTagsFromNAND(in->myDev, theChunk,
                                                            tags,
@@ -3618,7 +3615,7 @@ static int yaffs_PutChunkIntoFile(yaffs_Object *in, int chunkInInode,
                        }
 
                        if ((inScan > 0) &&
-                           (in->myDev->isYaffs2 ||
+                           (in->myDev->param.isYaffs2 ||
                             existingChunk <= 0 ||
                             ((existingSerial + 1) & 3) == newSerial)) {
                                /* Forward scanning.
@@ -3678,8 +3675,8 @@ void yaffs_DeleteChunk(yaffs_Device *dev, int chunkId, int markNAND, int lyn)
                return;
 
        dev->nDeletions++;
-       block = chunkId / dev->nChunksPerBlock;
-       page = chunkId % dev->nChunksPerBlock;
+       block = chunkId / dev->param.nChunksPerBlock;
+       page = chunkId % dev->param.nChunksPerBlock;
 
 
        if (!yaffs_CheckChunkBit(dev, block, page))
@@ -3693,7 +3690,7 @@ void yaffs_DeleteChunk(yaffs_Device *dev, int chunkId, int markNAND, int lyn)
          (TSTR("line %d delete of chunk %d" TENDSTR), lyn, chunkId));
 
        if (markNAND &&
-           bi->blockState != YAFFS_BLOCK_STATE_COLLECTING && !dev->isYaffs2) {
+           bi->blockState != YAFFS_BLOCK_STATE_COLLECTING && !dev->param.isYaffs2) {
 
                yaffs_InitialiseTags(&tags);
 
@@ -3766,7 +3763,7 @@ static int yaffs_WriteChunkDataToObject(yaffs_Object *in, int chunkInInode,
            (prevChunkId > 0) ? prevTags.serialNumber + 1 : 1;
        newTags.byteCount = nBytes;
 
-       if (nBytes < 1 || nBytes > dev->totalBytesPerChunk) {
+       if (nBytes < 1 || nBytes > dev->param.totalBytesPerChunk) {
                T(YAFFS_TRACE_ERROR,
                (TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), nBytes));
                YBUG();
@@ -3952,7 +3949,7 @@ int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force,
                        /* If this was a shrink, then mark the block that the chunk lives on */
                        if (isShrink) {
                                bi = yaffs_GetBlockInfo(in->myDev,
-                                       newChunkId / in->myDev->nChunksPerBlock);
+                                       newChunkId / in->myDev->param.nChunksPerBlock);
                                bi->hasShrinkHeader = 1;
                        }
 
@@ -3986,7 +3983,7 @@ static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj)
        yaffs_Device *dev = obj->myDev;
        int i;
        yaffs_ChunkCache *cache;
-       int nCaches = obj->myDev->nShortOpCaches;
+       int nCaches = obj->myDev->param.nShortOpCaches;
 
        for (i = 0; i < nCaches; i++) {
                cache = &dev->srCache[i];
@@ -4006,7 +4003,7 @@ static void yaffs_FlushFilesChunkCache(yaffs_Object *obj)
        int i;
        yaffs_ChunkCache *cache;
        int chunkWritten = 0;
-       int nCaches = obj->myDev->nShortOpCaches;
+       int nCaches = obj->myDev->param.nShortOpCaches;
 
        if (nCaches > 0) {
                do {
@@ -4058,7 +4055,7 @@ static void yaffs_FlushFilesChunkCache(yaffs_Object *obj)
 void yaffs_FlushEntireDeviceCache(yaffs_Device *dev)
 {
        yaffs_Object *obj;
-       int nCaches = dev->nShortOpCaches;
+       int nCaches = dev->param.nShortOpCaches;
        int i;
 
        /* Find a dirty object in the cache and flush it...
@@ -4089,8 +4086,8 @@ static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev)
 {
        int i;
 
-       if (dev->nShortOpCaches > 0) {
-               for (i = 0; i < dev->nShortOpCaches; i++) {
+       if (dev->param.nShortOpCaches > 0) {
+               for (i = 0; i < dev->param.nShortOpCaches; i++) {
                        if (!dev->srCache[i].object)
                                return &dev->srCache[i];
                }
@@ -4107,7 +4104,7 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
        int i;
        int pushout;
 
-       if (dev->nShortOpCaches > 0) {
+       if (dev->param.nShortOpCaches > 0) {
                /* Try find a non-dirty one... */
 
                cache = yaffs_GrabChunkCacheWorker(dev);
@@ -4126,7 +4123,7 @@ static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
                        cache = NULL;
                        pushout = -1;
 
-                       for (i = 0; i < dev->nShortOpCaches; i++) {
+                       for (i = 0; i < dev->param.nShortOpCaches; i++) {
                                if (dev->srCache[i].object &&
                                    !dev->srCache[i].locked &&
                                    (dev->srCache[i].lastUse < usage || !cache)) {
@@ -4156,8 +4153,8 @@ static yaffs_ChunkCache *yaffs_FindChunkCache(const yaffs_Object *obj,
 {
        yaffs_Device *dev = obj->myDev;
        int i;
-       if (dev->nShortOpCaches > 0) {
-               for (i = 0; i < dev->nShortOpCaches; i++) {
+       if (dev->param.nShortOpCaches > 0) {
+               for (i = 0; i < dev->param.nShortOpCaches; i++) {
                        if (dev->srCache[i].object == obj &&
                            dev->srCache[i].chunkId == chunkId) {
                                dev->cacheHits++;
@@ -4174,11 +4171,11 @@ static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache,
                                int isAWrite)
 {
 
-       if (dev->nShortOpCaches > 0) {
+       if (dev->param.nShortOpCaches > 0) {
                if (dev->srLastUse < 0 || dev->srLastUse > 100000000) {
                        /* Reset the cache usages */
                        int i;
-                       for (i = 1; i < dev->nShortOpCaches; i++)
+                       for (i = 1; i < dev->param.nShortOpCaches; i++)
                                dev->srCache[i].lastUse = 0;
 
                        dev->srLastUse = 0;
@@ -4199,7 +4196,7 @@ static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache,
  */
 static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId)
 {
-       if (object->myDev->nShortOpCaches > 0) {
+       if (object->myDev->param.nShortOpCaches > 0) {
                yaffs_ChunkCache *cache = yaffs_FindChunkCache(object, chunkId);
 
                if (cache)
@@ -4215,9 +4212,9 @@ static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in)
        int i;
        yaffs_Device *dev = in->myDev;
 
-       if (dev->nShortOpCaches > 0) {
+       if (dev->param.nShortOpCaches > 0) {
                /* Invalidate it. */
-               for (i = 0; i < dev->nShortOpCaches; i++) {
+               for (i = 0; i < dev->param.nShortOpCaches; i++) {
                        if (dev->srCache[i].object == in)
                                dev->srCache[i].object = NULL;
                }
@@ -4649,7 +4646,7 @@ static int yaffs_WriteCheckpointData(yaffs_Device *dev)
 {
        int ok = 1;
 
-       if (dev->skipCheckpointWrite || !dev->isYaffs2) {
+       if (dev->param.skipCheckpointWrite || !dev->param.isYaffs2) {
                T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint write" TENDSTR)));
                ok = 0;
        }
@@ -4692,7 +4689,7 @@ static int yaffs_ReadCheckpointData(yaffs_Device *dev)
 {
        int ok = 1;
 
-       if (dev->skipCheckpointRead || !dev->isYaffs2) {
+       if (dev->param.skipCheckpointRead || !dev->param.isYaffs2) {
                T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint read" TENDSTR)));
                ok = 0;
        }
@@ -4740,8 +4737,8 @@ static void yaffs_InvalidateCheckpoint(yaffs_Device *dev)
                        dev->blocksInCheckpoint > 0) {
                dev->isCheckpointed = 0;
                yaffs_CheckpointInvalidateStream(dev);
-               if (dev->superBlock && dev->markSuperBlockDirty)
-                       dev->markSuperBlockDirty(dev->superBlock);
+               if (dev->param.markSuperBlockDirty)
+                       dev->param.markSuperBlockDirty(dev->context);
        }
 }
 
@@ -4828,8 +4825,8 @@ int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 *buffer, loff_t offset,
                 * or we're using inband tags then use the cache (if there is caching)
                 * else bypass the cache.
                 */
-               if (cache || nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
-                       if (dev->nShortOpCaches > 0) {
+               if (cache || nToCopy != dev->nDataBytesPerChunk || dev->param.inbandTags) {
+                       if (dev->param.nShortOpCaches > 0) {
 
                                /* If we can't find the data in the cache, then load it up. */
 
@@ -4952,11 +4949,11 @@ int yaffs_WriteDataToFile(yaffs_Object *in, const __u8 *buffer, loff_t offset,
                        nToWriteBack = dev->nDataBytesPerChunk;
                }
 
-               if (nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
+               if (nToCopy != dev->nDataBytesPerChunk || dev->param.inbandTags) {
                        /* An incomplete start or end chunk (or maybe both start and end chunk),
                         * or we're using inband tags, so we want to use the cache buffers.
                         */
-                       if (dev->nShortOpCaches > 0) {
+                       if (dev->param.nShortOpCaches > 0) {
                                yaffs_ChunkCache *cache;
                                /* If we can't find the data in the cache, then load the cache */
                                cache = yaffs_FindChunkCache(in, chunk);
@@ -5093,10 +5090,10 @@ static void yaffs_PruneResizedChunks(yaffs_Object *in, int newSize)
                chunkId = yaffs_FindAndDeleteChunkInFile(in, i, NULL);
                if (chunkId > 0) {
                        if (chunkId <
-                           (dev->internalStartBlock * dev->nChunksPerBlock)
+                           (dev->internalStartBlock * dev->param.nChunksPerBlock)
                            || chunkId >=
                            ((dev->internalEndBlock +
-                             1) * dev->nChunksPerBlock)) {
+                             1) * dev->param.nChunksPerBlock)) {
                                T(YAFFS_TRACE_ALWAYS,
                                  (TSTR("Found daft chunkId %d for %d" TENDSTR),
                                   chunkId, i));
@@ -5232,7 +5229,7 @@ static int yaffs_DoGenericObjectDeletion(yaffs_Object *in)
        /* First off, invalidate the file's data in the cache, without flushing. */
        yaffs_InvalidateWholeChunkCache(in);
 
-       if (in->myDev->isYaffs2 && (in->parent != in->myDev->deletedDir)) {
+       if (in->myDev->param.isYaffs2 && (in->parent != in->myDev->deletedDir)) {
                /* Move to the unlinked directory so we have a record that it was deleted. */
                yaffs_ChangeObjectName(in, in->myDev->deletedDir, _Y("deleted"), 0, 0);
 
@@ -5269,7 +5266,7 @@ static int yaffs_UnlinkFileIfNeeded(yaffs_Object *in)
                   in->objectId));
                in->deleted = 1;
                in->myDev->nDeletedFiles++;
-               if (1 || in->myDev->isYaffs2)
+               if (1 || in->myDev->param.isYaffs2)
                        yaffs_ResizeFile(in, 0);
                yaffs_SoftDeleteFile(in);
        } else {
@@ -5770,7 +5767,7 @@ static int yaffs_Scan(yaffs_Device *dev)
                        T(YAFFS_TRACE_SCAN_DEBUG,
                          (TSTR("Block empty " TENDSTR)));
                        dev->nErasedBlocks++;
-                       dev->nFreeChunks += dev->nChunksPerBlock;
+                       dev->nFreeChunks += dev->param.nChunksPerBlock;
                }
        }
 
@@ -5793,10 +5790,10 @@ static int yaffs_Scan(yaffs_Device *dev)
                deleted = 0;
 
                /* For each chunk in each block that needs scanning....*/
-               for (c = 0; !alloc_failed && c < dev->nChunksPerBlock &&
+               for (c = 0; !alloc_failed && c < dev->param.nChunksPerBlock &&
                     state == YAFFS_BLOCK_STATE_NEEDS_SCANNING; c++) {
                        /* Read the tags and decide what to do */
-                       chunk = blk * dev->nChunksPerBlock + c;
+                       chunk = blk * dev->param.nChunksPerBlock + c;
 
                        result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
                                                        &tags);
@@ -5834,7 +5831,7 @@ static int yaffs_Scan(yaffs_Device *dev)
 
                                }
 
-                               dev->nFreeChunks += (dev->nChunksPerBlock - c);
+                               dev->nFreeChunks += (dev->param.nChunksPerBlock - c);
                        } else if (tags.chunkId > 0) {
                                /* chunkId > 0 so it is a data chunk... */
                                unsigned int endpos;
@@ -5867,7 +5864,7 @@ static int yaffs_Scan(yaffs_Device *dev)
                                    endpos) {
                                        in->variant.fileVariant.
                                            scannedFileSize = endpos;
-                                       if (!dev->useHeaderFileSize) {
+                                       if (!dev->param.useHeaderFileSize) {
                                                in->variant.fileVariant.
                                                    fileSize =
                                                    in->variant.fileVariant.
@@ -6046,7 +6043,7 @@ static int yaffs_Scan(yaffs_Device *dev)
                                                /* Todo got a problem */
                                                break;
                                        case YAFFS_OBJECT_TYPE_FILE:
-                                               if (dev->useHeaderFileSize)
+                                               if (dev->param.useHeaderFileSize)
 
                                                        in->variant.fileVariant.
                                                            fileSize =
@@ -6237,7 +6234,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev)
        yaffs_BlockIndex *blockIndex = NULL;
        int altBlockIndex = 0;
 
-       if (!dev->isYaffs2) {
+       if (!dev->param.isYaffs2) {
                T(YAFFS_TRACE_SCAN,
                  (TSTR("yaffs_ScanBackwards is only for YAFFS2!" TENDSTR)));
                return YAFFS_FAIL;
@@ -6300,7 +6297,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev)
                        T(YAFFS_TRACE_SCAN_DEBUG,
                          (TSTR("Block empty " TENDSTR)));
                        dev->nErasedBlocks++;
-                       dev->nFreeChunks += dev->nChunksPerBlock;
+                       dev->nFreeChunks += dev->param.nChunksPerBlock;
                } else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
 
                        /* Determine the highest sequence number */
@@ -6385,7 +6382,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev)
 
                /* For each chunk in each block that needs scanning.... */
                foundChunksInBlock = 0;
-               for (c = dev->nChunksPerBlock - 1;
+               for (c = dev->param.nChunksPerBlock - 1;
                     !alloc_failed && c >= 0 &&
                     (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
                      state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
@@ -6393,7 +6390,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev)
                         * Read the tags and decide what to do
                         */
 
-                       chunk = blk * dev->nChunksPerBlock + c;
+                       chunk = blk * dev->param.nChunksPerBlock + c;
 
                        result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
                                                        &tags);
@@ -6528,7 +6525,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev)
                                }
 
                                if (!in ||
-                                   (!in->valid && dev->disableLazyLoad) ||
+                                   (!in->valid && dev->param.disableLazyLoad) ||
                                    tags.extraShadows ||
                                    (!in->valid &&
                                    (tags.objectId == YAFFS_OBJECTID_ROOT ||
@@ -6546,7 +6543,7 @@ static int yaffs_ScanBackwards(yaffs_Device *dev)
 
                                        oh = (yaffs_ObjectHeader *) chunkData;
 
-                                       if (dev->inbandTags) {
+                                       if (dev->param.inbandTags) {
                                                /* Fix up the header if they got corrupted by inband tags */
                                                oh->shadowsObject = oh->inbandShadowsObject;
                                                oh->isShrink = oh->inbandIsShrink;
@@ -6975,8 +6972,8 @@ static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj)
 
        yaffs_VerifyDirectory(parent);
 
-       if (dev && dev->removeObjectCallback)
-               dev->removeObjectCallback(obj);
+       if (dev && dev->param.removeObjectCallback)
+               dev->param.removeObjectCallback(obj);
 
 
        ylist_del_init(&obj->siblings);
@@ -7350,30 +7347,32 @@ static int yaffs_CheckDevFunctions(const yaffs_Device *dev)
 {
 
        /* Common functions, gotta have */
-       if (!dev->eraseBlockInNAND || !dev->initialiseNAND)
+       if (!dev->param.eraseBlockInNAND || !dev->param.initialiseNAND)
                return 0;
 
 #ifdef CONFIG_YAFFS_YAFFS2
 
        /* Can use the "with tags" style interface for yaffs1 or yaffs2 */
-       if (dev->writeChunkWithTagsToNAND &&
-           dev->readChunkWithTagsFromNAND &&
-           !dev->writeChunkToNAND &&
-           !dev->readChunkFromNAND &&
-           dev->markNANDBlockBad && dev->queryNANDBlock)
+       if (dev->param.writeChunkWithTagsToNAND &&
+           dev->param.readChunkWithTagsFromNAND &&
+           !dev->param.writeChunkToNAND &&
+           !dev->param.readChunkFromNAND &&
+           dev->param.markNANDBlockBad &&
+           dev->param.queryNANDBlock)
                return 1;
 #endif
 
        /* Can use the "spare" style interface for yaffs1 */
-       if (!dev->isYaffs2 &&
-           !dev->writeChunkWithTagsToNAND &&
-           !dev->readChunkWithTagsFromNAND &&
-           dev->writeChunkToNAND &&
-           dev->readChunkFromNAND &&
-           !dev->markNANDBlockBad && !dev->queryNANDBlock)
+       if (!dev->param.isYaffs2 &&
+           !dev->param.writeChunkWithTagsToNAND &&
+           !dev->param.readChunkWithTagsFromNAND &&
+           dev->param.writeChunkToNAND &&
+           dev->param.readChunkFromNAND &&
+           !dev->param.markNANDBlockBad &&
+           !dev->param.queryNANDBlock)
                return 1;
 
-       return 0;               /* bad */
+       return 0;       /* bad */
 }
 
 
@@ -7420,35 +7419,35 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
                return YAFFS_FAIL;
        }
 
-       dev->internalStartBlock = dev->startBlock;
-       dev->internalEndBlock = dev->endBlock;
+       dev->internalStartBlock = dev->param.startBlock;
+       dev->internalEndBlock = dev->param.endBlock;
        dev->blockOffset = 0;
        dev->chunkOffset = 0;
        dev->nFreeChunks = 0;
 
        dev->gcBlock = -1;
 
-       if (dev->startBlock == 0) {
-               dev->internalStartBlock = dev->startBlock + 1;
-               dev->internalEndBlock = dev->endBlock + 1;
+       if (dev->param.startBlock == 0) {
+               dev->internalStartBlock = dev->param.startBlock + 1;
+               dev->internalEndBlock = dev->param.endBlock + 1;
                dev->blockOffset = 1;
-               dev->chunkOffset = dev->nChunksPerBlock;
+               dev->chunkOffset = dev->param.nChunksPerBlock;
        }
 
        /* Check geometry parameters. */
 
-       if ((!dev->inbandTags && dev->isYaffs2 && dev->totalBytesPerChunk < 1024) ||
-           (!dev->isYaffs2 && dev->totalBytesPerChunk < 512) ||
-           (dev->inbandTags && !dev->isYaffs2) ||
-            dev->nChunksPerBlock < 2 ||
-            dev->nReservedBlocks < 2 ||
+       if ((!dev->param.inbandTags && dev->param.isYaffs2 && dev->param.totalBytesPerChunk < 1024) ||
+           (!dev->param.isYaffs2 && dev->param.totalBytesPerChunk < 512) ||
+           (dev->param.inbandTags && !dev->param.isYaffs2) ||
+            dev->param.nChunksPerBlock < 2 ||
+            dev->param.nReservedBlocks < 2 ||
             dev->internalStartBlock <= 0 ||
             dev->internalEndBlock <= 0 ||
-            dev->internalEndBlock <= (dev->internalStartBlock + dev->nReservedBlocks + 2)) {   /* otherwise it is too small */
+            dev->internalEndBlock <= (dev->internalStartBlock + dev->param.nReservedBlocks + 2)) {     /* otherwise it is too small */
                T(YAFFS_TRACE_ALWAYS,
                  (TSTR
                   ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s, inbandTags %d "
-                   TENDSTR), dev->totalBytesPerChunk, dev->isYaffs2 ? "2" : "", dev->inbandTags));
+                   TENDSTR), dev->param.totalBytesPerChunk, dev->param.isYaffs2 ? "2" : "", dev->param.inbandTags));
                return YAFFS_FAIL;
        }
 
@@ -7459,10 +7458,10 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        }
 
        /* Sort out space for inband tags, if required */
-       if (dev->inbandTags)
-               dev->nDataBytesPerChunk = dev->totalBytesPerChunk - sizeof(yaffs_PackedTags2TagsPart);
+       if (dev->param.inbandTags)
+               dev->nDataBytesPerChunk = dev->param.totalBytesPerChunk - sizeof(yaffs_PackedTags2TagsPart);
        else
-               dev->nDataBytesPerChunk = dev->totalBytesPerChunk;
+               dev->nDataBytesPerChunk = dev->param.totalBytesPerChunk;
 
        /* Got the right mix of functions? */
        if (!yaffs_CheckDevFunctions(dev)) {
@@ -7509,12 +7508,12 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
         * We need to find the next power of 2 > than internalEndBlock
         */
 
-       x = dev->nChunksPerBlock * (dev->internalEndBlock + 1);
+       x = dev->param.nChunksPerBlock * (dev->internalEndBlock + 1);
 
        bits = ShiftsGE(x);
 
        /* Set up tnode width if wide tnodes are enabled. */
-       if (!dev->wideTnodesDisabled) {
+       if (!dev->param.wideTnodesDisabled) {
                /* bits must be even so that we end up with 32-bit words */
                if (bits & 1)
                        bits++;
@@ -7541,7 +7540,7 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
 
        dev->chunkGroupSize = 1 << dev->chunkGroupBits;
 
-       if (dev->nChunksPerBlock < dev->chunkGroupSize) {
+       if (dev->param.nChunksPerBlock < dev->chunkGroupSize) {
                /* We have a problem because the soft delete won't work if
                 * the chunk group size > chunks per block.
                 * This can be remedied by using larger "virtual blocks".
@@ -7581,13 +7580,13 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
 
 
        if (!init_failed &&
-           dev->nShortOpCaches > 0) {
+           dev->param.nShortOpCaches > 0) {
                int i;
                void *buf;
-               int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache);
+               int srCacheBytes = dev->param.nShortOpCaches * sizeof(yaffs_ChunkCache);
 
-               if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES)
-                       dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
+               if (dev->param.nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES)
+                       dev->param.nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
 
                dev->srCache =  YMALLOC(srCacheBytes);
 
@@ -7596,11 +7595,11 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
                if (dev->srCache)
                        memset(dev->srCache, 0, srCacheBytes);
 
-               for (i = 0; i < dev->nShortOpCaches && buf; i++) {
+               for (i = 0; i < dev->param.nShortOpCaches && buf; i++) {
                        dev->srCache[i].object = NULL;
                        dev->srCache[i].lastUse = 0;
                        dev->srCache[i].dirty = 0;
-                       dev->srCache[i].data = buf = YMALLOC_DMA(dev->totalBytesPerChunk);
+                       dev->srCache[i].data = buf = YMALLOC_DMA(dev->param.totalBytesPerChunk);
                }
                if (!buf)
                        init_failed = 1;
@@ -7611,13 +7610,13 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
        dev->cacheHits = 0;
 
        if (!init_failed) {
-               dev->gcCleanupList = YMALLOC(dev->nChunksPerBlock * sizeof(__u32));
+               dev->gcCleanupList = YMALLOC(dev->param.nChunksPerBlock * sizeof(__u32));
                if (!dev->gcCleanupList)
                        init_failed = 1;
        }
 
-       if (dev->isYaffs2)
-               dev->useHeaderFileSize = 1;
+       if (dev->param.isYaffs2)
+               dev->param.useHeaderFileSize = 1;
 
        if (!init_failed && !yaffs_InitialiseBlocks(dev))
                init_failed = 1;
@@ -7631,7 +7630,7 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
 
        if (!init_failed) {
                /* Now scan the flash. */
-               if (dev->isYaffs2) {
+               if (dev->param.isYaffs2) {
                        if (yaffs_CheckpointRestore(dev)) {
                                yaffs_CheckObjectDetailsLoaded(dev->rootDir);
                                T(YAFFS_TRACE_ALWAYS,
@@ -7672,7 +7671,7 @@ int yaffs_GutsInitialise(yaffs_Device *dev)
 
                yaffs_StripDeletedObjects(dev);
                yaffs_FixHangingObjects(dev);
-               if(dev->emptyLostAndFound)
+               if(dev->param.emptyLostAndFound)
                        yaffs_EmptyLostAndFound(dev);
        }
 
@@ -7715,10 +7714,10 @@ void yaffs_Deinitialise(yaffs_Device *dev)
                yaffs_DeinitialiseBlocks(dev);
                yaffs_DeinitialiseTnodes(dev);
                yaffs_DeinitialiseObjects(dev);
-               if (dev->nShortOpCaches > 0 &&
+               if (dev->param.nShortOpCaches > 0 &&
                    dev->srCache) {
 
-                       for (i = 0; i < dev->nShortOpCaches; i++) {
+                       for (i = 0; i < dev->param.nShortOpCaches; i++) {
                                if (dev->srCache[i].data)
                                        YFREE(dev->srCache[i].data);
                                dev->srCache[i].data = NULL;
@@ -7735,8 +7734,8 @@ void yaffs_Deinitialise(yaffs_Device *dev)
 
                dev->isMounted = 0;
 
-               if (dev->deinitialiseNAND)
-                       dev->deinitialiseNAND(dev);
+               if (dev->param.deinitialiseNAND)
+                       dev->param.deinitialiseNAND(dev);
        }
 }
 
@@ -7757,7 +7756,7 @@ static int yaffs_CountFreeChunks(yaffs_Device *dev)
                case YAFFS_BLOCK_STATE_COLLECTING:
                case YAFFS_BLOCK_STATE_FULL:
                        nFree +=
-                           (dev->nChunksPerBlock - blk->pagesInUse +
+                           (dev->param.nChunksPerBlock - blk->pagesInUse +
                             blk->softDeletions);
                        break;
                default:
@@ -7787,21 +7786,21 @@ int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
 
        /* Now count the number of dirty chunks in the cache and subtract those */
 
-       for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) {
+       for (nDirtyCacheChunks = 0, i = 0; i < dev->param.nShortOpCaches; i++) {
                if (dev->srCache[i].dirty)
                        nDirtyCacheChunks++;
        }
 
        nFree -= nDirtyCacheChunks;
 
-       nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
+       nFree -= ((dev->param.nReservedBlocks + 1) * dev->param.nChunksPerBlock);
 
        /* Now we figure out how much to reserve for the checkpoint and report that... */
        blocksForCheckpoint = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
        if (blocksForCheckpoint < 0)
                blocksForCheckpoint = 0;
 
-       nFree -= (blocksForCheckpoint * dev->nChunksPerBlock);
+       nFree -= (blocksForCheckpoint * dev->param.nChunksPerBlock);
 
        if (nFree < 0)
                nFree = 0;
index 55395dc..53ab280 100644 (file)
 #define YAFFS_OBJECTID_UNLINKED                3
 #define YAFFS_OBJECTID_DELETED         4
 
-/* Sseudo object ids for checkpointing */
+/* Pseudo object ids for checkpointing */
 #define YAFFS_OBJECTID_SB_HEADER       0x10
 #define YAFFS_OBJECTID_CHECKPOINT_DATA 0x20
 #define YAFFS_SEQUENCE_CHECKPOINT_DATA  0x21
 
-/* */
 
 #define YAFFS_MAX_SHORT_OP_CACHES      20
 
@@ -119,11 +118,7 @@ typedef struct {
        int dirty;
        int nBytes;             /* Only valid if the cache is dirty */
        int locked;             /* Can't push out or flush while locked. */
-#ifdef CONFIG_YAFFS_YAFFS2
        __u8 *data;
-#else
-       __u8 data[YAFFS_BYTES_PER_CHUNK];
-#endif
 } yaffs_ChunkCache;
 
 
@@ -234,6 +229,8 @@ typedef enum {
        YAFFS_BLOCK_STATE_UNKNOWN = 0,
 
        YAFFS_BLOCK_STATE_SCANNING,
+        /* Being scanned */
+
        YAFFS_BLOCK_STATE_NEEDS_SCANNING,
        /* The block might have something on it (ie it is allocating or full, perhaps empty)
         * but it needs to be scanned to determine its true state.
@@ -249,21 +246,23 @@ typedef enum {
        /* This block is partially allocated.
         * At least one page holds valid data.
         * This is the one currently being used for page
-        * allocation. Should never be more than one of these
+        * allocation. Should never be more than one of these.
+         * If a block is only partially allocated at mount it is treated as full.
         */
 
        YAFFS_BLOCK_STATE_FULL,
        /* All the pages in this block have been allocated.
+         * If a block was only partially allocated when mounted we treat
+         * it as fully allocated.
         */
 
        YAFFS_BLOCK_STATE_DIRTY,
-       /* All pages have been allocated and deleted.
+       /* The block was full and now all chunks have been deleted.
         * Erase me, reuse me.
         */
 
        YAFFS_BLOCK_STATE_CHECKPOINT,
-       /* This block is assigned to holding checkpoint data.
-        */
+       /* This block is assigned to holding checkpoint data. */
 
        YAFFS_BLOCK_STATE_COLLECTING,
        /* This block is being garbage collected */
@@ -528,12 +527,17 @@ typedef struct {
 /*----------------- Device ---------------------------------*/
 
 
-struct yaffs_DeviceStruct {
-       struct ylist_head devList;
+struct yaffs_DeviceParamStruct {
        const char *name;
 
-       /* Entry parameters set up way early. Yaffs sets up the rest.*/
-       int nDataBytesPerChunk; /* Should be a power of 2 >= 512 */
+       /*
+         * Entry parameters set up way early. Yaffs sets up the rest.
+         * The structure should be zeroed out before use so that unused
+         * and defualt values are zero.
+         */
+
+       int inbandTags;          /* Use unband tags */
+       __u32 totalBytesPerChunk; /* Should be >= 512, does not need to be a power of 2 */
        int nChunksPerBlock;    /* does not need to be a power of 2 */
        int spareBytesPerChunk; /* spare area size */
        int startBlock;         /* Start block we're allowed to use */
@@ -542,27 +546,20 @@ struct yaffs_DeviceStruct {
                                /* reserved blocks on NOR and RAM. */
 
 
-       /* Stuff used by the shared space checkpointing mechanism */
-       /* If this value is zero, then this mechanism is disabled */
-
-/*     int nCheckpointReservedBlocks; */ /* Blocks to reserve for checkpoint data */
-
-
        int nShortOpCaches;     /* If <= 0, then short op caching is disabled, else
-                                * the number of short op caches (don't use too many)
+                                * the number of short op caches (don't use too many).
+                                 * 10 to 20 is a good bet.
                                 */
-
-       int useHeaderFileSize;  /* Flag to determine if we should use file sizes from the header */
-
        int useNANDECC;         /* Flag to decide whether or not to use NANDECC on data (yaffs1) */
        int noTagsECC;          /* Flag to decide whether or not to do ECC on packed tags (yaffs2) */ 
-       
-       int disableLazyLoad;    /* Disable lazy loading on this device */
 
-       void *genericDevice;    /* Pointer to device context
-                                * On an mtd this holds the mtd pointer.
-                                */
-       void *superBlock;
+       int isYaffs2;           /* Use yaffs2 mode on this device */
+
+       int emptyLostAndFound;  /* Auto-empty lost+found directory on mount */
+
+       /* Checkpoint control. Can be set before or after initialisation */
+       __u8 skipCheckpointRead;
+       __u8 skipCheckpointWrite;
 
        /* NAND access functions (Must be set before calling YAFFS)*/
 
@@ -589,8 +586,6 @@ struct yaffs_DeviceStruct {
                               yaffs_BlockState *state, __u32 *sequenceNumber);
 #endif
 
-       int isYaffs2;
-
        /* The removeObjectCallback function must be supplied by OS flavours that
         * need it.
          * yaffs direct uses it to implement the faster readdir.
@@ -598,23 +593,37 @@ struct yaffs_DeviceStruct {
         */
        void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
 
-       /* Callback to mark the superblock dirsty */
-       void (*markSuperBlockDirty)(void *superblock);
+       /* Callback to mark the superblock dirty */
+       void (*markSuperBlockDirty)(struct yaffs_DeviceStruct *dev);
 
+        /* Debug control flags. Don't use unless you know what you're doing */
+       int useHeaderFileSize;  /* Flag to determine if we should use file sizes from the header */
+       int disableLazyLoad;    /* Disable lazy loading on this device */
        int wideTnodesDisabled; /* Set to disable wide tnodes */
 
        YCHAR *pathDividers;    /* String of legal path dividers */
 
+       
 
        /* End of stuff that must be set before initialisation. */
+};
 
-       /* Checkpoint control. Can be set before or after initialisation */
-       __u8 skipCheckpointRead;
-       __u8 skipCheckpointWrite;
+typedef struct yaffs_DeviceParamStruct yaffs_DeviceParam;
+
+struct yaffs_DeviceStruct {
+       struct yaffs_DeviceParamStruct param;
+
+        /* Context storage. Holds extra OS specific data for this device */
+
+       void *context;
 
        /* Runtime parameters. Set up by YAFFS. */
+       int nDataBytesPerChunk; 
 
-       __u16 chunkGroupBits;   /* 0 for devices <= 32MB. else log2(nchunks) - 16 */
+        /* Non-wide tnode stuff */
+       __u16 chunkGroupBits;   /* Number of bits that need to be resolved if
+                                 * the tnodes are not wide enough.
+                                 */
        __u16 chunkGroupSize;   /* == 2^^chunkGroupBits */
 
        /* Stuff to support wide tnodes */
@@ -626,27 +635,10 @@ struct yaffs_DeviceStruct {
        __u32 chunkDiv;   /* Divisor after shifting: 1 for power-of-2 sizes */
        __u32 chunkMask;  /* Mask to use for power-of-2 case */
 
-       /* Stuff to handle inband tags */
-       int inbandTags;
-       __u32 totalBytesPerChunk;
-
-#ifdef __KERNEL__
 
-       struct semaphore sem;   /* Semaphore for waiting on erasure.*/
-       struct semaphore grossLock;     /* Gross locking semaphore */
-       struct rw_semaphore dirLock; /* Lock the directory structure */
-       __u8 *spareBuffer;      /* For mtdif2 use. Don't know the size of the buffer
-                                * at compile time so we have to allocate it.
-
-                                */
-       void (*putSuperFunc) (struct super_block *sb);
-        struct ylist_head searchContexts;
-
-#endif
 
        int isMounted;
        int readOnly;
-
        int isCheckpointed;
 
 
@@ -688,7 +680,6 @@ struct yaffs_DeviceStruct {
        __u32 allocationPage;
        int allocationBlockFinder;      /* Used to search for next allocation block */
 
-       /* Runtime state */
        int nTnodesCreated;
        yaffs_Tnode *freeTnodes;
        int nFreeTnodes;
@@ -715,23 +706,6 @@ struct yaffs_DeviceStruct {
        __u32 *gcCleanupList;   /* objects to delete at the end of a GC. */
        int nonAggressiveSkip;  /* GC state/mode */
 
-       /* Statistcs */
-       int nPageWrites;
-       int nPageReads;
-       int nBlockErasures;
-       int nErasureFailures;
-       int nGCCopies;
-       int garbageCollections;
-       int passiveGarbageCollections;
-       int nRetriedWrites;
-       int nRetiredBlocks;
-       int eccFixed;
-       int eccUnfixed;
-       int tagsEccFixed;
-       int tagsEccUnfixed;
-       int nDeletions;
-       int nUnmarkedDeletions;
-
        int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */
 
        /* Special directories */
@@ -771,8 +745,23 @@ struct yaffs_DeviceStruct {
        unsigned sequenceNumber;        /* Sequence number of currently allocating block */
        unsigned oldestDirtySequence;
        
-       /* Auto empty lost and found directory on mount */
-       int emptyLostAndFound;
+
+       /* Statistcs */
+       int nPageWrites;
+       int nPageReads;
+       int nBlockErasures;
+       int nErasureFailures;
+       int nGCCopies;
+       int garbageCollections;
+       int passiveGarbageCollections;
+       int nRetriedWrites;
+       int nRetiredBlocks;
+       int eccFixed;
+       int eccUnfixed;
+       int tagsEccFixed;
+       int tagsEccUnfixed;
+       int nDeletions;
+       int nUnmarkedDeletions;
 };
 
 typedef struct yaffs_DeviceStruct yaffs_Device;
@@ -891,10 +880,7 @@ yaffs_Object *yaffs_LostNFound(yaffs_Device *dev);
 void yfsd_WinFileTimeNow(__u32 target[2]);
 #endif
 
-#ifdef __KERNEL__
-
 void yaffs_HandleDeferedFree(yaffs_Object *obj);
-#endif
 
 /* Debug dump  */
 int yaffs_DumpObject(yaffs_Object *obj);
index 306e188..25d92ed 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 const char *yaffs_mtdif_c_version =
-       "$Id: yaffs_mtdif.c,v 1.22 2009-03-06 17:20:51 wookey Exp $";
+       "$Id: yaffs_mtdif.c,v 1.23 2010-02-18 01:18:04 charles Exp $";
 
 #include "yportenv.h"
 
@@ -24,6 +24,8 @@ const char *yaffs_mtdif_c_version =
 #include "linux/time.h"
 #include "linux/mtd/nand.h"
 
+#include "yaffs_linux.h"
+
 #if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 18))
 static struct nand_oobinfo yaffs_oobinfo = {
        .useecc = 1,
@@ -74,7 +76,7 @@ static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
 int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
                             const __u8 *data, const yaffs_Spare *spare)
 {
-       struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
 #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
        struct mtd_oob_ops ops;
 #endif
@@ -89,7 +91,7 @@ int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
                retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk,
                                &dummy, data);
        else if (spare) {
-               if (dev->useNANDECC) {
+               if (dev->param.useNANDECC) {
                        translate_spare2oob(spare, spareAsBytes);
                        ops.mode = MTD_OOB_AUTO;
                        ops.ooblen = 8; /* temp hack */
@@ -107,7 +109,7 @@ int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
        __u8 *spareAsBytes = (__u8 *) spare;
 
        if (data && spare) {
-               if (dev->useNANDECC)
+               if (dev->param.useNANDECC)
                        retval =
                            mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
                                           &dummy, data, spareAsBytes,
@@ -138,7 +140,7 @@ int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
 int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
                              yaffs_Spare *spare)
 {
-       struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
 #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
        struct mtd_oob_ops ops;
 #endif
@@ -153,7 +155,7 @@ int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
                retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
                                &dummy, data);
        else if (spare) {
-               if (dev->useNANDECC) {
+               if (dev->param.useNANDECC) {
                        ops.mode = MTD_OOB_AUTO;
                        ops.ooblen = 8; /* temp hack */
                } else {
@@ -165,14 +167,14 @@ int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
                ops.ooboffs = 0;
                ops.oobbuf = spareAsBytes;
                retval = mtd->read_oob(mtd, addr, &ops);
-               if (dev->useNANDECC)
+               if (dev->param.useNANDECC)
                        translate_oob2spare(spare, spareAsBytes);
        }
 #else
        __u8 *spareAsBytes = (__u8 *) spare;
 
        if (data && spare) {
-               if (dev->useNANDECC) {
+               if (dev->param.useNANDECC) {
                        /* Careful, this call adds 2 ints */
                        /* to the end of the spare data.  Calling function */
                        /* should allocate enough memory for spare, */
@@ -207,25 +209,22 @@ int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
 
 int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
 {
-       struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
        __u32 addr =
            ((loff_t) blockNumber) * dev->nDataBytesPerChunk
-               * dev->nChunksPerBlock;
+               * dev->param.nChunksPerBlock;
        struct erase_info ei;
+       
        int retval = 0;
 
        ei.mtd = mtd;
        ei.addr = addr;
-       ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock;
+       ei.len = dev->nDataBytesPerChunk * dev->param.nChunksPerBlock;
        ei.time = 1000;
        ei.retries = 2;
        ei.callback = NULL;
        ei.priv = (u_long) dev;
 
-       /* Todo finish off the ei if required */
-
-       sema_init(&dev->sem, 0);
-
        retval = mtd->erase(mtd, &ei);
 
        if (retval == 0)
index 990e0fb..16171e0 100644 (file)
@@ -28,6 +28,7 @@
 #include "yaffs_guts.h"
 #include "yaffs_packedtags1.h"
 #include "yaffs_tagscompat.h"  /* for yaffs_CalcTagsECC */
+#include "yaffs_linux.h"
 
 #include "linux/kernel.h"
 #include "linux/version.h"
@@ -37,7 +38,7 @@
 /* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
 #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
 
-const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.12 2010-01-11 04:06:46 charles Exp $";
+const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.13 2010-02-18 01:18:04 charles Exp $";
 
 #ifndef CONFIG_YAFFS_9BYTE_TAGS
 # define YTAG1_SIZE 8
@@ -92,7 +93,7 @@ static struct nand_ecclayout nand_oob_16 = {
 int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev,
        int chunkInNAND, const __u8 *data, const yaffs_ExtendedTags *etags)
 {
-       struct mtd_info *mtd = dev->genericDevice;
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
        int chunkBytes = dev->nDataBytesPerChunk;
        loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
        struct mtd_oob_ops ops;
@@ -170,7 +171,7 @@ static int rettags(yaffs_ExtendedTags *etags, int eccResult, int retval)
 int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
        int chunkInNAND, __u8 *data, yaffs_ExtendedTags *etags)
 {
-       struct mtd_info *mtd = dev->genericDevice;
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
        int chunkBytes = dev->nDataBytesPerChunk;
        loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
        int eccres = YAFFS_ECC_RESULT_NO_ERROR;
@@ -281,8 +282,8 @@ int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
  */
 int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
 {
-       struct mtd_info *mtd = dev->genericDevice;
-       int blocksize = dev->nChunksPerBlock * dev->nDataBytesPerChunk;
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
+       int blocksize = dev->param.nChunksPerBlock * dev->nDataBytesPerChunk;
        int retval;
 
        yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad\n", blockNo);
@@ -322,8 +323,8 @@ static int nandmtd1_TestPrerequists(struct mtd_info *mtd)
 int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
        yaffs_BlockState *pState, __u32 *pSequenceNumber)
 {
-       struct mtd_info *mtd = dev->genericDevice;
-       int chunkNo = blockNo * dev->nChunksPerBlock;
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
+       int chunkNo = blockNo * dev->param.nChunksPerBlock;
        loff_t addr = (loff_t)chunkNo * dev->nDataBytesPerChunk;
        yaffs_ExtendedTags etags;
        int state = YAFFS_BLOCK_STATE_DEAD;
index e6b08e4..8cbe19f 100644 (file)
@@ -14,7 +14,7 @@
 /* mtd interface for YAFFS2 */
 
 const char *yaffs_mtdif2_c_version =
-       "$Id: yaffs_mtdif2.c,v 1.26 2010-01-11 21:43:18 charles Exp $";
+       "$Id: yaffs_mtdif2.c,v 1.27 2010-02-18 01:18:04 charles Exp $";
 
 #include "yportenv.h"
 #include "yaffs_trace.h"
@@ -27,6 +27,8 @@ const char *yaffs_mtdif2_c_version =
 
 #include "yaffs_packedtags2.h"
 
+#include "yaffs_linux.h"
+
 /* NB For use with inband tags....
  * We assume that the data buffer is of size totalBytersPerChunk so that we can also
  * use it to load the tags.
@@ -35,7 +37,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
                                      const __u8 *data,
                                      const yaffs_ExtendedTags *tags)
 {
-       struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
 #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
        struct mtd_oob_ops ops;
 #else
@@ -47,8 +49,8 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
 
        yaffs_PackedTags2 pt;
 
-       int packed_tags_size = dev->noTagsECC ? sizeof(pt.t) : sizeof(pt);
-       void * packed_tags_ptr = dev->noTagsECC ? (void *) &pt.t : (void *)&pt;
+       int packed_tags_size = dev->param.noTagsECC ? sizeof(pt.t) : sizeof(pt);
+       void * packed_tags_ptr = dev->param.noTagsECC ? (void *) &pt.t : (void *)&pt;
 
        T(YAFFS_TRACE_MTD,
          (TSTR
@@ -56,7 +58,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
            TENDSTR), chunkInNAND, data, tags));
 
 
-       addr  = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
+       addr  = ((loff_t) chunkInNAND) * dev->param.totalBytesPerChunk;
 
        /* For yaffs2 writing there must be both data and tags.
         * If we're using inband tags, then the tags are stuffed into
@@ -64,30 +66,30 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
         */
        if (!data || !tags)
                BUG();
-       else if (dev->inbandTags) {
+       else if (dev->param.inbandTags) {
                yaffs_PackedTags2TagsPart *pt2tp;
                pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
                yaffs_PackTags2TagsPart(pt2tp, tags);
        } else
-               yaffs_PackTags2(&pt, tags, !dev->noTagsECC);
+               yaffs_PackTags2(&pt, tags, !dev->param.noTagsECC);
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
        ops.mode = MTD_OOB_AUTO;
-       ops.ooblen = (dev->inbandTags) ? 0 : packed_tags_size;
-       ops.len = dev->totalBytesPerChunk;
+       ops.ooblen = (dev->param.inbandTags) ? 0 : packed_tags_size;
+       ops.len = dev->param.totalBytesPerChunk;
        ops.ooboffs = 0;
        ops.datbuf = (__u8 *)data;
-       ops.oobbuf = (dev->inbandTags) ? NULL : packed_tags_ptr;
+       ops.oobbuf = (dev->param.inbandTags) ? NULL : packed_tags_ptr;
        retval = mtd->write_oob(mtd, addr, &ops);
 
 #else
-       if (!dev->inbandTags) {
+       if (!dev->param.inbandTags) {
                retval =
                    mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
                                   &dummy, data, (__u8 *) packed_tags_ptr, NULL);
        } else {
                retval =
-                   mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy,
+                   mtd->write(mtd, addr, dev->param.totalBytesPerChunk, &dummy,
                               data);
        }
 #endif
@@ -101,7 +103,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
 int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
                                       __u8 *data, yaffs_ExtendedTags *tags)
 {
-       struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
 #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
        struct mtd_oob_ops ops;
 #endif
@@ -109,19 +111,19 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
        int retval = 0;
        int localData = 0;
 
-       loff_t addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
+       loff_t addr = ((loff_t) chunkInNAND) * dev->param.totalBytesPerChunk;
 
        yaffs_PackedTags2 pt;
 
-       int packed_tags_size = dev->noTagsECC ? sizeof(pt.t) : sizeof(pt);
-       void * packed_tags_ptr = dev->noTagsECC ? (void *) &pt.t: (void *)&pt;
+       int packed_tags_size = dev->param.noTagsECC ? sizeof(pt.t) : sizeof(pt);
+       void * packed_tags_ptr = dev->param.noTagsECC ? (void *) &pt.t: (void *)&pt;
 
        T(YAFFS_TRACE_MTD,
          (TSTR
           ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
            TENDSTR), chunkInNAND, data, tags));
 
-       if (dev->inbandTags) {
+       if (dev->param.inbandTags) {
 
                if (!data) {
                        localData = 1;
@@ -133,8 +135,8 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
 
 
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-       if (dev->inbandTags || (data && !tags))
-               retval = mtd->read(mtd, addr, dev->totalBytesPerChunk,
+       if (dev->param.inbandTags || (data && !tags))
+               retval = mtd->read(mtd, addr, dev->param.totalBytesPerChunk,
                                &dummy, data);
        else if (tags) {
                ops.mode = MTD_OOB_AUTO;
@@ -142,11 +144,11 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
                ops.len = data ? dev->nDataBytesPerChunk : packed_tags_size;
                ops.ooboffs = 0;
                ops.datbuf = data;
-               ops.oobbuf = dev->spareBuffer;
+               ops.oobbuf = yaffs_DeviceToContext(dev)->spareBuffer;
                retval = mtd->read_oob(mtd, addr, &ops);
        }
 #else
-       if (!dev->inbandTags && data && tags) {
+       if (!dev->param.inbandTags && data && tags) {
 
                retval = mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
                                          &dummy, data, dev->spareBuffer,
@@ -156,7 +158,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
                        retval =
                            mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
                                      data);
-               if (!dev->inbandTags && tags)
+               if (!dev->param.inbandTags && tags)
                        retval =
                            mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
                                          dev->spareBuffer);
@@ -164,7 +166,7 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
 #endif
 
 
-       if (dev->inbandTags) {
+       if (dev->param.inbandTags) {
                if (tags) {
                        yaffs_PackedTags2TagsPart *pt2tp;
                        pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
@@ -172,8 +174,8 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
                }
        } else {
                if (tags) {
-                       memcpy(packed_tags_ptr, dev->spareBuffer, packed_tags_size);
-                       yaffs_UnpackTags2(tags, &pt, !dev->noTagsECC);
+                       memcpy(packed_tags_ptr, yaffs_DeviceToContext(dev)->spareBuffer, packed_tags_size);
+                       yaffs_UnpackTags2(tags, &pt, !dev->param.noTagsECC);
                }
        }
 
@@ -190,15 +192,15 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
 
 int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
 {
-       struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
        int retval;
        T(YAFFS_TRACE_MTD,
          (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo));
 
        retval =
            mtd->block_markbad(mtd,
-                              blockNo * dev->nChunksPerBlock *
-                              dev->totalBytesPerChunk);
+                              blockNo * dev->param.nChunksPerBlock *
+                              dev->param.totalBytesPerChunk);
 
        if (retval == 0)
                return YAFFS_OK;
@@ -210,15 +212,15 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
 int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
                            yaffs_BlockState *state, __u32 *sequenceNumber)
 {
-       struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
+       struct mtd_info *mtd = yaffs_DeviceToContext(dev)->mtd;
        int retval;
 
        T(YAFFS_TRACE_MTD,
          (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), blockNo));
        retval =
            mtd->block_isbad(mtd,
-                            blockNo * dev->nChunksPerBlock *
-                            dev->totalBytesPerChunk);
+                            blockNo * dev->param.nChunksPerBlock *
+                            dev->param.totalBytesPerChunk);
 
        if (retval) {
                T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));
@@ -229,7 +231,7 @@ int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
                yaffs_ExtendedTags t;
                nandmtd2_ReadChunkWithTagsFromNAND(dev,
                                                   blockNo *
-                                                  dev->nChunksPerBlock, NULL,
+                                                  dev->param.nChunksPerBlock, NULL,
                                                   &t);
 
                if (t.chunkUsed) {
index 0a76ca0..9622c66 100644 (file)
@@ -12,7 +12,7 @@
  */
 
 const char *yaffs_nand_c_version =
-       "$Id: yaffs_nand.c,v 1.11 2009-09-09 03:03:01 charles Exp $";
+       "$Id: yaffs_nand.c,v 1.12 2010-02-18 01:18:04 charles Exp $";
 
 #include "yaffs_nand.h"
 #include "yaffs_tagscompat.h"
@@ -35,8 +35,8 @@ int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
        if (!tags)
                tags = &localTags;
 
-       if (dev->readChunkWithTagsFromNAND)
-               result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
+       if (dev->param.readChunkWithTagsFromNAND)
+               result = dev->param.readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
                                                      tags);
        else
                result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
@@ -46,7 +46,7 @@ int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
        if (tags &&
           tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR) {
 
-               yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
+               yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->param.nChunksPerBlock);
                yaffs_HandleChunkError(dev, bi);
        }
 
@@ -80,8 +80,8 @@ int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
                YBUG();
        }
 
-       if (dev->writeChunkWithTagsToNAND)
-               return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
+       if (dev->param.writeChunkWithTagsToNAND)
+               return dev->param.writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
                                                     tags);
        else
                return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
@@ -95,8 +95,8 @@ int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo)
        blockNo -= dev->blockOffset;
 
 
-       if (dev->markNANDBlockBad)
-               return dev->markNANDBlockBad(dev, blockNo);
+       if (dev->param.markNANDBlockBad)
+               return dev->param.markNANDBlockBad(dev, blockNo);
        else
                return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
 }
@@ -108,8 +108,8 @@ int yaffs_QueryInitialBlockState(yaffs_Device *dev,
 {
        blockNo -= dev->blockOffset;
 
-       if (dev->queryNANDBlock)
-               return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
+       if (dev->param.queryNANDBlock)
+               return dev->param.queryNANDBlock(dev, blockNo, state, sequenceNumber);
        else
                return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
                                                             state,
@@ -126,14 +126,15 @@ int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
 
        dev->nBlockErasures++;
 
-       result = dev->eraseBlockInNAND(dev, blockInNAND);
+       result = dev->param.eraseBlockInNAND(dev, blockInNAND);
 
        return result;
 }
 
 int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
 {
-       return dev->initialiseNAND(dev);
+       if(dev->param.initialiseNAND)
+               return dev->param.initialiseNAND(dev);
 }
 
 
index 020eee5..1ab054f 100644 (file)
@@ -164,14 +164,14 @@ 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->param.startBlock * dev->param.nChunksPerBlock) {
                T(YAFFS_TRACE_ERROR,
                  (TSTR("**>> yaffs chunk %d is not valid" TENDSTR),
                   chunkInNAND));
                return YAFFS_FAIL;
        }
 
-       return dev->writeChunkToNAND(dev, chunkInNAND, data, spare);
+       return dev->param.writeChunkToNAND(dev, chunkInNAND, data, spare);
 }
 
 static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
@@ -190,8 +190,8 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
                spare = &localSpare;
        }
 
-       if (!dev->useNANDECC) {
-               retVal = dev->readChunkFromNAND(dev, chunkInNAND, data, spare);
+       if (!dev->param.useNANDECC) {
+               retVal = dev->param.readChunkFromNAND(dev, chunkInNAND, data, spare);
                if (data && doErrorCorrection) {
                        /* Do ECC correction */
                        /* Todo handle any errors */
@@ -252,7 +252,7 @@ static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
 
                memset(&nspare, 0, sizeof(nspare));
 
-               retVal = dev->readChunkFromNAND(dev, chunkInNAND, data,
+               retVal = dev->param.readChunkFromNAND(dev, chunkInNAND, data,
                                        (yaffs_Spare *) &nspare);
                memcpy(spare, &nspare, sizeof(yaffs_Spare));
                if (data && doErrorCorrection) {
@@ -305,10 +305,10 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
        static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK];
        static __u8 data[YAFFS_BYTES_PER_CHUNK];
        /* Might as well always allocate the larger size for */
-       /* dev->useNANDECC == true; */
+       /* dev->param.useNANDECC == true; */
        static __u8 spare[sizeof(struct yaffs_NANDSpare)];
 
-       dev->readChunkFromNAND(dev, chunkInNAND, data, (yaffs_Spare *) spare);
+       dev->param.readChunkFromNAND(dev, chunkInNAND, data, (yaffs_Spare *) spare);
 
        if (!init) {
                memset(cmpbuf, 0xff, YAFFS_BYTES_PER_CHUNK);
@@ -331,7 +331,7 @@ static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
 
 static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND)
 {
-       int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
+       int blockInNAND = chunkInNAND / dev->param.nChunksPerBlock;
 
        /* Mark the block for retirement */
        yaffs_GetBlockInfo(dev, blockInNAND + dev->blockOffset)->needsRetiring = 1;
@@ -363,7 +363,7 @@ static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
 
 static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND)
 {
-       int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
+       int blockInNAND = chunkInNAND / dev->param.nChunksPerBlock;
 
        /* Mark the block for retirement */
        yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1;
@@ -422,7 +422,7 @@ int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
 
                tags.serialNumber = eTags->serialNumber;
 
-               if (!dev->useNANDECC && data)
+               if (!dev->param.useNANDECC && data)
                        yaffs_CalcECC(data, &spare);
 
                yaffs_LoadTagsIntoSpare(&spare, &tags);
@@ -496,9 +496,9 @@ int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
 
        spare.blockStatus = 'Y';
 
-       yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL,
+       yaffs_WriteChunkToNAND(dev, blockInNAND * dev->param.nChunksPerBlock, NULL,
                               &spare);
-       yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1,
+       yaffs_WriteChunkToNAND(dev, blockInNAND * dev->param.nChunksPerBlock + 1,
                               NULL, &spare);
 
        return YAFFS_OK;
@@ -523,9 +523,9 @@ int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
 
        *sequenceNumber = 0;
 
-       yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock, NULL,
+       yaffs_ReadChunkFromNAND(dev, blockNo * dev->param.nChunksPerBlock, NULL,
                                &spare0, &dummy, 1);
-       yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock + 1, NULL,
+       yaffs_ReadChunkFromNAND(dev, blockNo * dev->param.nChunksPerBlock + 1, NULL,
                                &spare1, &dummy, 1);
 
        if (yaffs_CountBits(spare0.blockStatus & spare1.blockStatus) < 7)