/*
 * YAFFS: Yet another FFS. A NAND-flash specific file system. 
 * yaffs_ramem.c  NAND emulation on top of a chunk of RAM
 *
 * Copyright (C) 2002 Aleph One Ltd.
 *   for Toby Churchill Ltd and Brightstar Engineering
 *
 * Created by Charles Manning <charles@aleph1.co.uk>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */
 //yaffs_ramem2k.c: RAM emulation in-kernel for 2K pages (YAFFS2)


const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.1 2005/08/09 01:00:37 charles Exp $";

#ifndef __KERNEL__
#define CONFIG_YAFFS_RAM_ENABLED
#else
#include <linux/config.h>
#endif

#ifdef CONFIG_YAFFS_RAM_ENABLED

#include "yportenv.h"

#include "yaffs_nandemul2k.h"
#include "yaffs_guts.h"
#include "yaffsinterface.h"
#include "devextras.h"
#include "yaffs_packedtags2.h"



#define EM_SIZE_IN_MEG (32)
#define PAGE_DATA_SIZE  (2048)
#define PAGE_SPARE_SIZE (64)
#define PAGES_PER_BLOCK (64)



#define EM_SIZE_IN_BYTES (EM_SIZE_IN_MEG * (1<<20))

#define PAGE_TOTAL_SIZE (PAGE_DATA_SIZE+PAGE_SPARE_SIZE)

#define BLOCK_TOTAL_SIZE (PAGES_PER_BLOCK * PAGE_TOTAL_SIZE)

#define BLOCKS_PER_MEG ((1<<20)/(PAGES_PER_BLOCK * PAGE_DATA_SIZE))


typedef struct 
{
	__u8 data[PAGE_TOTAL_SIZE]; // Data + spare
	int empty;      // is this empty?
} nandemul_Page;


typedef struct
{
	nandemul_Page *page[PAGES_PER_BLOCK];
	int damaged;	
} nandemul_Block;



typedef struct
{
	nandemul_Block**block;
	int nBlocks;
} nandemul_Device;

static nandemul_Device ned;

static int sizeInMB = EM_SIZE_IN_MEG;


static void nandemul_yield(int n)
{
#ifdef __KERNEL__
	if(n > 0) schedule_timeout(n);
#endif

}


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));
		blk->page[i]->empty = 1;
	}
	nandemul_yield(2);
}


static int nandemul2k_CalcNBlocks(void)
{
	return EM_SIZE_IN_MEG * BLOCKS_PER_MEG;
}



static int  CheckInit(void)
{
	static int initialised = 0;
	
	int i,j;
	
	int fail = 0;
	int nBlocks; 

	int nAllocated = 0;
	
	if(initialised) 
	{
		return YAFFS_OK;
	}
	
	
	ned.nBlocks = nBlocks = nandemul2k_CalcNBlocks();

	
	ned.block = YMALLOC(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] = YMALLOC(sizeof(nandemul_Block))))
		{
		 fail = 1;
		}  
		else
		{
			for(j = 0; j < PAGES_PER_BLOCK; j++)
			{
				if((blk->page[j] = YMALLOC(sizeof(nandemul_Page))) == 0)
				{
					fail = 1;
				}
			}
			nandemul_ReallyEraseBlock(i);
			ned.block[i]->damaged = 0;
			nAllocated++;
		}
	}
	
	if(fail)
	{
		//Todo thump pages
		
		for(i = 0; i < nAllocated; i++)
		{
			YFREE(ned.block[i]);
		}
		YFREE(ned.block);
		
		T(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 nandemul2k_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags)
{
	int blk;
	int pg;
	int i;
	
	__u8 *x;

	
	blk = chunkInNAND/PAGES_PER_BLOCK;
	pg = chunkInNAND%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_PackTags2((yaffs_PackedTags2 *)x,tags);
			
	}
	
	if(tags || data)
	{
		nandemul_yield(1);
	}

	return YAFFS_OK;
}


int nandemul2k_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags)
{
	int blk;
	int pg;
	
	__u8 *x;

	
	
	blk = chunkInNAND/PAGES_PER_BLOCK;
	pg = chunkInNAND%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_UnpackTags2(tags,(yaffs_PackedTags2 *)x);
	}

	return YAFFS_OK;
}


static int nandemul2k_CheckChunkErased(yaffs_Device *dev,int chunkInNAND)
{
	int blk;
	int pg;
	int i;

	
	
	blk = chunkInNAND/PAGES_PER_BLOCK;
	pg = chunkInNAND%PAGES_PER_BLOCK;
	
	
	for(i = 0; i < PAGE_TOTAL_SIZE; i++)
	{
		if(ned.block[blk]->page[pg]->data[i] != 0xFF)
		{
			return YAFFS_FAIL;
		}
	}

	return YAFFS_OK;

}

int nandemul2k_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
{
	
	
	if(blockNumber < 0 || blockNumber >= ned.nBlocks)
	{
		T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber));
	}
	else if(ned.block[blockNumber]->damaged)
	{
		T(YAFFS_TRACE_ALWAYS,("Attempt to erase damaged block %d\n",blockNumber));
	}
	else
	{
		nandemul_ReallyEraseBlock(blockNumber);
	}
	
	return YAFFS_OK;
}

int nandemul2k_InitialiseNAND(yaffs_Device *dev)
{
	CheckInit();
	return YAFFS_OK;
}
 
int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
{
	
	__u8 *x;
	
	x = &ned.block[blockNo]->page[0]->data[PAGE_DATA_SIZE];
	
	memset(x,0,sizeof(yaffs_PackedTags2));
	
	
	return YAFFS_OK;
	
}

int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber)
{
	yaffs_ExtendedTags tags;
	int chunkNo;

	*sequenceNumber = 0;
	
	chunkNo = blockNo * dev->nChunksPerBlock;
	
	nandemul2k_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags);
	if(tags.blockBad)
	{
		*state = YAFFS_BLOCK_STATE_DEAD;
	}
	else if(!tags.chunkUsed)
	{
		*state = YAFFS_BLOCK_STATE_EMPTY;
	}
	else if(tags.chunkUsed)
	{
		*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
		*sequenceNumber = tags.sequenceNumber;
	}
	return YAFFS_OK;
}

int nandemul2k_GetBytesPerChunk(void) { return PAGE_DATA_SIZE;}

int nandemul2k_GetChunksPerBlock(void) { return PAGES_PER_BLOCK; }
int nandemul2k_GetNumberOfBlocks(void) {return nandemul2k_CalcNBlocks();}


#endif //YAFFS_RAM_ENABLED

