/*
 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
 *
 * Copyright (C) 2002-2007 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.
 */

/* XXX U-BOOT XXX */
#include <common.h>
#include <malloc.h>

const char *yaffs_checkptrw_c_version =
    "$Id: yaffs_checkptrw.c,v 1.14 2007/05/15 20:07:40 charles Exp $";


#include "yaffs_checkptrw.h"


static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
{

	int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;

	T(YAFFS_TRACE_CHECKPOINT,
		(TSTR("checkpt blocks available = %d" TENDSTR),
		blocksAvailable));


	return (blocksAvailable <= 0) ? 0 : 1;
}


static int yaffs_CheckpointErase(yaffs_Device *dev)
{

	int i;


	if(!dev->eraseBlockInNAND)
		return 0;
	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checking blocks %d to %d"TENDSTR),
		dev->internalStartBlock,dev->internalEndBlock));

	for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
		if(bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT){
			T(YAFFS_TRACE_CHECKPOINT,(TSTR("erasing checkpt block %d"TENDSTR),i));
			if(dev->eraseBlockInNAND(dev,i- dev->blockOffset /* realign */)){
				bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
				dev->nErasedBlocks++;
				dev->nFreeChunks += dev->nChunksPerBlock;
			}
			else {
				dev->markNANDBlockBad(dev,i);
				bi->blockState = YAFFS_BLOCK_STATE_DEAD;
			}
		}
	}

	dev->blocksInCheckpoint = 0;

	return 1;
}


static void yaffs_CheckpointFindNextErasedBlock(yaffs_Device *dev)
{
	int  i;
	int blocksAvailable = dev->nErasedBlocks - dev->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));

	if(dev->checkpointNextBlock >= 0 &&
	   dev->checkpointNextBlock <= dev->internalEndBlock &&
	   blocksAvailable > 0){

		for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
			if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY){
				dev->checkpointNextBlock = i + 1;
				dev->checkpointCurrentBlock = i;
				T(YAFFS_TRACE_CHECKPOINT,(TSTR("allocating checkpt block %d"TENDSTR),i));
				return;
			}
		}
	}
	T(YAFFS_TRACE_CHECKPOINT,(TSTR("out of checkpt blocks"TENDSTR)));

	dev->checkpointNextBlock = -1;
	dev->checkpointCurrentBlock = -1;
}

static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev)
{
	int  i;
	yaffs_ExtendedTags tags;

	T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: start:  blocks %d next %d" TENDSTR),
		dev->blocksInCheckpoint, dev->checkpointNextBlock));

	if(dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
		for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
			int chunk = i * dev->nChunksPerBlock;
			int realignedChunk = chunk - dev->chunkOffset;

			dev->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));

			if(tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA){
				/* Right kind of block */
				dev->checkpointNextBlock = tags.objectId;
				dev->checkpointCurrentBlock = i;
				dev->checkpointBlockList[dev->blocksInCheckpoint] = i;
				dev->blocksInCheckpoint++;
				T(YAFFS_TRACE_CHECKPOINT,(TSTR("found checkpt block %d"TENDSTR),i));
				return;
			}
		}

	T(YAFFS_TRACE_CHECKPOINT,(TSTR("found no more checkpt blocks"TENDSTR)));

	dev->checkpointNextBlock = -1;
	dev->checkpointCurrentBlock = -1;
}


int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
{

	/* Got the functions we need? */
	if (!dev->writeChunkWithTagsToNAND ||
	    !dev->readChunkWithTagsFromNAND ||
	    !dev->eraseBlockInNAND ||
	    !dev->markNANDBlockBad)
		return 0;

	if(forWriting && !yaffs_CheckpointSpaceOk(dev))
		return 0;

	if(!dev->checkpointBuffer)
		dev->checkpointBuffer = YMALLOC_DMA(dev->nDataBytesPerChunk);
	if(!dev->checkpointBuffer)
		return 0;


	dev->checkpointPageSequence = 0;

	dev->checkpointOpenForWrite = forWriting;

	dev->checkpointByteCount = 0;
	dev->checkpointSum = 0;
	dev->checkpointXor = 0;
	dev->checkpointCurrentBlock = -1;
	dev->checkpointCurrentChunk = -1;
	dev->checkpointNextBlock = dev->internalStartBlock;

	/* Erase all the blocks in the checkpoint area */
	if(forWriting){
		memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
		dev->checkpointByteOffset = 0;
		return yaffs_CheckpointErase(dev);


	} else {
		int i;
		/* Set to a value that will kick off a read */
		dev->checkpointByteOffset = dev->nDataBytesPerChunk;
		/* A checkpoint block list of 1 checkpoint block per 16 block is (hopefully)
		 * going to be way more than we need */
		dev->blocksInCheckpoint = 0;
		dev->checkpointMaxBlocks = (dev->internalEndBlock - dev->internalStartBlock)/16 + 2;
		dev->checkpointBlockList = YMALLOC(sizeof(int) * dev->checkpointMaxBlocks);
		for(i = 0; i < dev->checkpointMaxBlocks; i++)
			dev->checkpointBlockList[i] = -1;
	}

	return 1;
}

int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum)
{
	__u32 compositeSum;
	compositeSum =  (dev->checkpointSum << 8) | (dev->checkpointXor & 0xFF);
	*sum = compositeSum;
	return 1;
}

static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
{

	int chunk;
	int realignedChunk;

	yaffs_ExtendedTags tags;

	if(dev->checkpointCurrentBlock < 0){
		yaffs_CheckpointFindNextErasedBlock(dev);
		dev->checkpointCurrentChunk = 0;
	}

	if(dev->checkpointCurrentBlock < 0)
		return 0;

	tags.chunkDeleted = 0;
	tags.objectId = dev->checkpointNextBlock; /* Hint to next place to look */
	tags.chunkId = dev->checkpointPageSequence + 1;
	tags.sequenceNumber =  YAFFS_SEQUENCE_CHECKPOINT_DATA;
	tags.byteCount = dev->nDataBytesPerChunk;
	if(dev->checkpointCurrentChunk == 0){
		/* First chunk we write for the block? Set block state to
		   checkpoint */
		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointCurrentBlock);
		bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
		dev->blocksInCheckpoint++;
	}

	chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;


	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
		chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk,tags.objectId,tags.chunkId));

	realignedChunk = chunk - dev->chunkOffset;

	dev->writeChunkWithTagsToNAND(dev,realignedChunk,dev->checkpointBuffer,&tags);
	dev->checkpointByteOffset = 0;
	dev->checkpointPageSequence++;
	dev->checkpointCurrentChunk++;
	if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock){
		dev->checkpointCurrentChunk = 0;
		dev->checkpointCurrentBlock = -1;
	}
	memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);

	return 1;
}


int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
{
	int i=0;
	int ok = 1;


	__u8 * dataBytes = (__u8 *)data;



	if(!dev->checkpointBuffer)
		return 0;

	if(!dev->checkpointOpenForWrite)
		return -1;

	while(i < nBytes && ok) {



		dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes ;
		dev->checkpointSum += *dataBytes;
		dev->checkpointXor ^= *dataBytes;

		dev->checkpointByteOffset++;
		i++;
		dataBytes++;
		dev->checkpointByteCount++;


		if(dev->checkpointByteOffset < 0 ||
		   dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
			ok = yaffs_CheckpointFlushBuffer(dev);

	}

	return 	i;
}

int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
{
	int i=0;
	int ok = 1;
	yaffs_ExtendedTags tags;


	int chunk;
	int realignedChunk;

	__u8 *dataBytes = (__u8 *)data;

	if(!dev->checkpointBuffer)
		return 0;

	if(dev->checkpointOpenForWrite)
		return -1;

	while(i < nBytes && ok) {


		if(dev->checkpointByteOffset < 0 ||
		   dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {

		   	if(dev->checkpointCurrentBlock < 0){
				yaffs_CheckpointFindNextCheckpointBlock(dev);
				dev->checkpointCurrentChunk = 0;
			}

			if(dev->checkpointCurrentBlock < 0)
				ok = 0;
			else {

				chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock +
				          dev->checkpointCurrentChunk;

				realignedChunk = chunk - dev->chunkOffset;

	   			/* read in the next chunk */
	   			/* printf("read checkpoint page %d\n",dev->checkpointPage); */
				dev->readChunkWithTagsFromNAND(dev, realignedChunk,
							       dev->checkpointBuffer,
							      &tags);

				if(tags.chunkId != (dev->checkpointPageSequence + 1) ||
				   tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
				   ok = 0;

				dev->checkpointByteOffset = 0;
				dev->checkpointPageSequence++;
				dev->checkpointCurrentChunk++;

				if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
					dev->checkpointCurrentBlock = -1;
			}
		}

		if(ok){
			*dataBytes = dev->checkpointBuffer[dev->checkpointByteOffset];
			dev->checkpointSum += *dataBytes;
			dev->checkpointXor ^= *dataBytes;
			dev->checkpointByteOffset++;
			i++;
			dataBytes++;
			dev->checkpointByteCount++;
		}
	}

	return 	i;
}

int yaffs_CheckpointClose(yaffs_Device *dev)
{

	if(dev->checkpointOpenForWrite){
		if(dev->checkpointByteOffset != 0)
			yaffs_CheckpointFlushBuffer(dev);
	} else {
		int i;
		for(i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++){
			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointBlockList[i]);
			if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
				bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
			else {
				// Todo this looks odd...
			}
		}
		YFREE(dev->checkpointBlockList);
		dev->checkpointBlockList = NULL;
	}

	dev->nFreeChunks -= dev->blocksInCheckpoint * dev->nChunksPerBlock;
	dev->nErasedBlocks -= dev->blocksInCheckpoint;


	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint byte count %d" TENDSTR),
			dev->checkpointByteCount));

	if(dev->checkpointBuffer){
		/* free the buffer */
		YFREE(dev->checkpointBuffer);
		dev->checkpointBuffer = NULL;
		return 1;
	}
	else
		return 0;

}

int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
{
	/* Erase the first checksum block */

	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint invalidate"TENDSTR)));

	if(!yaffs_CheckpointSpaceOk(dev))
		return 0;

	return yaffs_CheckpointErase(dev);
}
