/*
 * 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.
 */

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



