#define BLOCKS_PER_MEG ((1<<20)/(PAGES_PER_BLOCK * PAGE_DATA_SIZE))
-typedef struct
+typedef struct
{
u8 data[PAGE_TOTAL_SIZE]; // Data + spare
int empty; // is this empty?
typedef struct
{
nandemul_Page *page[PAGES_PER_BLOCK];
- int damaged;
+ int damaged;
} nandemul_Block;
static void nandemul_ReallyEraseBlock(int blockNumber)
{
int i;
-
+
nandemul_Block *blk;
-
+
if(blockNumber < 0 || blockNumber >= ned.nBlocks)
{
return;
}
-
+
blk = ned.block[blockNumber];
-
+
for(i = 0; i < PAGES_PER_BLOCK; i++)
{
memset(blk->page[i],0xff,sizeof(nandemul_Page));
static int CheckInit(void)
{
static int initialised = 0;
-
+
int i,j;
-
+
int fail = 0;
- int nBlocks;
+ int nBlocks;
int nAllocated = 0;
-
- if(initialised)
+
+ if(initialised)
{
return YAFFS_OK;
}
-
-
+
+
ned.nBlocks = nBlocks = nandemul2k_CalcNBlocks();
-
+
ned.block = malloc(sizeof(nandemul_Block*) * nBlocks );
-
+
if(!ned.block) return YAFFS_FAIL;
-
-
-
-
+
+
+
+
for(i=fail=0; i <nBlocks; i++)
{
-
+
nandemul_Block *blk;
-
+
if(!(blk = ned.block[i] = malloc(sizeof(nandemul_Block))))
{
fail = 1;
- }
+ }
else
{
for(j = 0; j < PAGES_PER_BLOCK; j++)
nAllocated++;
}
}
-
+
if(fail)
{
//Todo thump pages
-
+
for(i = 0; i < nAllocated; i++)
{
kfree(ned.block[i]);
}
kfree(ned.block);
-
+
yaffs_trace(YAFFS_TRACE_ALWAYS,
"Allocation failed, could only allocate %dMB of %dMB requested.\n",
nAllocated/64,sizeInMB);
return 0;
}
-
+
ned.nBlocks = nBlocks;
-
+
initialised = 1;
-
+
return 1;
}
int blk;
int pg;
int i;
-
+
u8 *x;
-
+
blk = nand_chunk/PAGES_PER_BLOCK;
pg = nand_chunk%PAGES_PER_BLOCK;
-
-
+
+
if(data)
{
x = ned.block[blk]->page[pg]->data;
-
+
for(i = 0; i < PAGE_DATA_SIZE; i++)
{
x[i] &=data[i];
ned.block[blk]->page[pg]->empty = 0;
}
-
-
+
+
if(tags)
{
x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE];
-
- yaffs_pack_tags2((struct yaffs_packed_tags2 *)x,tags, !dev->param.no_tags_ecc);
-
+
+ yaffs_pack_tags2(dev, (struct yaffs_packed_tags2 *)x,tags, !dev->param.no_tags_ecc);
+
}
-
+
if(tags || data)
{
nandemul_yield(1);
{
int blk;
int pg;
-
+
u8 *x;
-
-
+
+
blk = nand_chunk/PAGES_PER_BLOCK;
pg = nand_chunk%PAGES_PER_BLOCK;
-
-
+
+
if(data)
{
memcpy(data,ned.block[blk]->page[pg]->data,PAGE_DATA_SIZE);
}
-
-
+
+
if(tags)
{
x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE];
-
- yaffs_unpack_tags2(tags,(struct yaffs_packed_tags2 *)x, !dev->param.no_tags_ecc);
+
+ yaffs_unpack_tags2(dev, tags,(struct yaffs_packed_tags2 *)x, !dev->param.no_tags_ecc);
}
return YAFFS_OK;
int pg;
int i;
-
-
+
+
blk = nand_chunk/PAGES_PER_BLOCK;
pg = nand_chunk%PAGES_PER_BLOCK;
-
-
+
+
for(i = 0; i < PAGE_TOTAL_SIZE; i++)
{
if(ned.block[blk]->page[pg]->data[i] != 0xFF)
int nandemul2k_EraseBlockInNAND(struct yaffs_dev *dev, int blockNumber)
{
-
-
+
+
if(blockNumber < 0 || blockNumber >= ned.nBlocks)
{
yaffs_trace(YAFFS_TRACE_ALWAYS,
{
nandemul_ReallyEraseBlock(blockNumber);
}
-
+
return YAFFS_OK;
}
CheckInit();
return YAFFS_OK;
}
-
+
int nandemul2k_MarkNANDBlockBad(struct yaffs_dev *dev, int block_no)
{
-
+
u8 *x;
-
+
x = &ned.block[block_no]->page[0]->data[PAGE_DATA_SIZE];
-
+
memset(x,0,sizeof(struct yaffs_packed_tags2));
-
-
+
+
return YAFFS_OK;
-
+
}
int nandemul2k_QueryNANDBlock(struct yaffs_dev *dev, int block_no, enum yaffs_block_state *state, u32 *seq_number)
int chunkNo;
*seq_number = 0;
-
+
chunkNo = block_no * dev->param.chunks_per_block;
-
+
nandemul2k_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
if(tags.block_bad)
{