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