changeset 356:7ee0cc4ba753

Rationalise context and parameter handling
author charles <charles>
date Thu, 18 Feb 2010 01:18:04 +0000
parents a52b8595f22c
children defe00903f31
files 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
diffstat 16 files changed, 515 insertions(+), 506 deletions(-) [+]
line wrap: on
line diff
--- a/direct/dtest.c
+++ b/direct/dtest.c
@@ -2258,7 +2258,6 @@ void checkpoint_upgrade_test(const char 
 	
 	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 
 	printf("Umount/mount attempt full\n");
 	yaffs_unmount(mountpt);
 	
-	SetCheckpointReservedBlocks(10);
 	yaffs_mount(mountpt);
 	
 	printf("unlink small file\n");
--- a/direct/yaffs_fileem.c
+++ b/direct/yaffs_fileem.c
@@ -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
 
 int yflash_InitialiseNAND(yaffs_Device *dev)
 {
-	dev->useNANDECC = 1; // force on useNANDECC which gets faked. 
-						 // This saves us doing ECC checks.
 	
 	return YAFFS_OK;
 }
--- a/direct/yaffs_fileem2k.c
+++ b/direct/yaffs_fileem2k.c
@@ -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(yaf
 	CheckInit();
 	
 	
-	if(dev->inbandTags){
+	if(dev->param.inbandTags){
 		
 		yaffs_PackedTags2TagsPart * pt2tp;
 		pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
@@ -195,7 +195,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaf
 		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(yaf
 			exit(1);
 		}
 		
-		if(written != dev->totalBytesPerChunk) return YAFFS_FAIL;
+		if(written != dev->param.totalBytesPerChunk) return YAFFS_FAIL;
 
 
 	}
@@ -252,7 +252,7 @@ int yflash2_WriteChunkWithTagsToNAND(yaf
 		
 			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(yaf
 			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(yaf
 		
 			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(yaf
 			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(ya
 	
 	
 	
-	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(ya
 		
 		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(ya
 			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(ya
 			{
 				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 yaff
 	
 	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_Devic
 		
 
 		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_
 
 	*sequenceNumber = 0;
 	
-	chunkNo = blockNo * dev->nChunksPerBlock;
+	chunkNo = blockNo * dev->param.nChunksPerBlock;
 	
 	yflash2_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
 	if(tags.blockBad)
--- a/direct/yaffs_norif1.c
+++ b/direct/yaffs_norif1.c
@@ -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 @@ const char *yaffs_norif1_c_version = "$I
 	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 @@ const char *yaffs_norif1_c_version = "$I
 	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_Devic
                 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_Devi
 	
 	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 
 	
 	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);
 		}
--- a/direct/yaffs_ramem2k.c
+++ b/direct/yaffs_ramem2k.c
@@ -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(
 	{
 		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
 	{
 		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 yaf
 
 	*sequenceNumber = 0;
 	
-	chunkNo = blockNo * dev->nChunksPerBlock;
+	chunkNo = blockNo * dev->param.nChunksPerBlock;
 	
 	nandemul2k_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
 	if(tags.blockBad)
--- a/direct/yaffscfg2k.c
+++ b/direct/yaffscfg2k.c
@@ -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;
-}
-
--- a/direct/yaffsfs.c
+++ b/direct/yaffsfs.c
@@ -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 = 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 *pat
 	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_DeviceConf
 
 	while(cfg && cfg->prefix && cfg->dev){
 		cfg->dev->isMounted = 0;
-		cfg->dev->removeObjectCallback = yaffsfs_RemoveObjectCallback;
+		cfg->dev->param.removeObjectCallback = yaffsfs_RemoveObjectCallback;
 		cfg++;
 	}
 
--- a/yaffs_checkptrw.c
+++ b/yaffs_checkptrw.c
@@ -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_D
 {
 	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_D
 
 			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_D
 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_CheckpointFindNextChec
 
 	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 *d
 	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(y
 		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(y
 
 	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 *d
 				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 *d
 
 				/* 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 *d
 				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->checkpointBlockList = NULL;
 	}
 
-	dev->nFreeChunks -= dev->blocksInCheckpoint * dev->nChunksPerBlock;
+	dev->nFreeChunks -= dev->blocksInCheckpoint * dev->param.nChunksPerBlock;
 	dev->nErasedBlocks -= dev->blocksInCheckpoint;
 
 
--- a/yaffs_fs.c
+++ b/yaffs_fs.c
@@ -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 par
 #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 yaf
 	.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 * yaff
                                 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(y
 
         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_blo
 		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_blo
 	} 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 inod
 
 #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
 
 	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);
-
-	if (dev->spareBuffer) {
-		YFREE(dev->spareBuffer);
-		dev->spareBuffer = NULL;
+	ylist_del_init(&(yaffs_DeviceToContext(dev)->contextList));
+
+	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
 
 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 sup
 }
 
 
-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_interna
 	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_interna
 	 * 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_interna
 		   "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;
-
-	dev->putSuperFunc = yaffs_MTDPutSuper;
-
-	dev->superBlock = (void *)sb;
-	dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;
-
+	param->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
+	param->initialiseNAND = nandmtd_InitialiseNAND;
+
+	yaffs_DeviceToContext(dev)->putSuperFunc = yaffs_MTDPutSuper;
+
+	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;
-
-	init_MUTEX(&dev->grossLock);
+        YINIT_LIST_HEAD(&(yaffs_DeviceToContext(dev)->searchContexts));
+        param->removeObjectCallback = yaffs_RemoveObjectCallback;
+
+	init_MUTEX(&(yaffs_DeviceToContext(dev)->grossLock));
 
 	yaffs_GrossLock(dev);
 
@@ -2484,14 +2511,14 @@ static struct proc_dir_entry *my_proc_en
 
 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 += 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 *
 
 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);
--- a/yaffs_guts.c
+++ b/yaffs_guts.c
@@ -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(y
 	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_Devi
 			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(ya
 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_Devi
 
 	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_Devi
 	/* 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_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_Devi
 				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
 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_
 	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_
 
 	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_Objec
 	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
 }
 
-#ifdef __KERNEL__
 
 void yaffs_HandleDeferedFree(yaffs_Object *obj)
 {
@@ -2100,7 +2099,6 @@ void yaffs_HandleDeferedFree(yaffs_Objec
 		yaffs_FreeObject(obj);
 }
 
-#endif
 
 static void yaffs_DeinitialiseObjects(yaffs_Device *dev)
 {
@@ -2223,11 +2221,10 @@ yaffs_Object *yaffs_FindObjectByNumber(y
 		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_
 	}
 
 	/* 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_
 
 	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_BlockNotDisqualifiedFro
 	__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_BlockNotDisqualifiedFro
 			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_FindBlockForGarbageColl
 
 	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_FindBlockForGarbageColl
 	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
 	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
 		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(
 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_CalcCheckpointBlocksReq
 
 		/* 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_CalcCheckpointBlocksReq
 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
 		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_Dev
 		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_Dev
 	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_Dev
 		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_D
 {
 	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(yaf
 
 		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(
 		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(
 			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_O
 			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_
 			}
 
 			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
 		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
 	  (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(
 	    (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_Objec
 			/* 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_ObjectHasCachedWriteDat
 	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(y
 	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(y
 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_GrabChunk
 {
 	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_GrabChunk
 	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_GrabChunk
 			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_FindChunk
 {
 	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_De
 				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_De
  */
 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_InvalidateWholeChunkCa
 	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(yaf
 {
 	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(yaff
 {
 	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(y
 			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 
 		 * 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 *
 			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(yaf
 		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
 	/* 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(yaff
 		   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_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_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_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_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_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_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_RemoveObjectFromDirect
 
 	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
 {
 
 	/* 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 *d
 		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 *d
 	}
 
 	/* 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 *d
 	 * 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 *d
 
 	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 *d
 
 
 	if (!init_failed &&
-	    dev->nShortOpCaches > 0) {
+	    dev->param.nShortOpCaches > 0) {
 		int i;
 		void *buf;
-		int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache);
-
-		if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES)
-			dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
+		int srCacheBytes = dev->param.nShortOpCaches * sizeof(yaffs_ChunkCache);
+
+		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 *d
 		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 *d
 	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 *d
 
 	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 *d
 
 		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 *de
 		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 *de
 
 		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_D
 		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_De
 
 	/* 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;
--- a/yaffs_guts.h
+++ b/yaffs_guts.h
@@ -81,12 +81,11 @@
 #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 */
+
+	int isYaffs2;           /* Use yaffs2 mode on this device */
 
-	void *genericDevice;	/* Pointer to device context
-				 * On an mtd this holds the mtd pointer.
-				 */
-	void *superBlock;
+	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_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);
--- a/yaffs_mtdif.c
+++ b/yaffs_mtdif.c
@@ -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(y
 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_Devic
 		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_Devic
 	__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_Devic
 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_Devi
 		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_Devi
 		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_Devi
 
 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)
--- a/yaffs_mtdif1.c
+++ b/yaffs_mtdif1.c
@@ -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 *e
 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(y
  */
 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(stru
 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;
--- a/yaffs_mtdif2.c
+++ b/yaffs_mtdif2.c
@@ -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(ya
 				      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(ya
 
 	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(ya
 	    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(ya
 	 */
 	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(ya
 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(y
 	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(y
 
 
 #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(y
 		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(y
 			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(y
 #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(y
 		}
 	} 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(y
 
 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 yaf
 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
 		yaffs_ExtendedTags t;
 		nandmtd2_ReadChunkWithTagsFromNAND(dev,
 						   blockNo *
-						   dev->nChunksPerBlock, NULL,
+						   dev->param.nChunksPerBlock, NULL,
 						   &t);
 
 		if (t.chunkUsed) {
--- a/yaffs_nand.c
+++ b/yaffs_nand.c
@@ -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(yaff
 	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(yaff
 	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
 		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
 	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_D
 {
 	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_
 
 	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);
 }
 
 
--- a/yaffs_tagscompat.c
+++ b/yaffs_tagscompat.c
@@ -164,14 +164,14 @@ static int yaffs_WriteChunkToNAND(struct
 				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(struc
 		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(struc
 
 		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
 	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
 
 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(yaff
 
 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_TagsCompatabilityWriteChunkWit
 
 		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_TagsCompatabilityMarkNANDBlock
 
 	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_TagsCompatabilityQueryNANDBloc
 
 	*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)