/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>

#include "cutils/log.h"

#include <mtd/mtd-user.h>

#include "mtdutils.h"

#ifdef RK3X
    #include "rk3xhack.h"
#endif

typedef struct BmlOverMtdReadContext {
	const MtdPartition *partition;
	char *buffer;
	size_t consumed;
	int fd;
} BmlOverMtdReadContext;

typedef struct BmlOverMtdWriteContext {
	const MtdPartition *partition;
	char *buffer;
	size_t stored;
	int fd;

	off_t* bad_block_offsets;
	int bad_block_alloc;
	int bad_block_count;
} BmlOverMtdWriteContext;


static BmlOverMtdReadContext *bml_over_mtd_read_partition(const MtdPartition *partition)
{
	BmlOverMtdReadContext *ctx = (BmlOverMtdReadContext*) malloc(sizeof(BmlOverMtdReadContext));
	if (ctx == NULL) return NULL;

	ctx->buffer = malloc(partition->erase_size);
	if (ctx->buffer == NULL) {
		free(ctx);
		return NULL;
	}

	char mtddevname[32];
	sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
	ctx->fd = open(mtddevname, O_RDONLY);
	if (ctx->fd < 0) {
		free(ctx);
		free(ctx->buffer);
		return NULL;
	}

	ctx->partition = partition;
	ctx->consumed = partition->erase_size;
	return ctx;
}

static void bml_over_mtd_read_close(BmlOverMtdReadContext *ctx)
{
	close(ctx->fd);
	free(ctx->buffer);
	free(ctx);
}

static BmlOverMtdWriteContext *bml_over_mtd_write_partition(const MtdPartition *partition)
{
	BmlOverMtdWriteContext *ctx = (BmlOverMtdWriteContext*) malloc(sizeof(BmlOverMtdWriteContext));
	if (ctx == NULL) return NULL;

	ctx->bad_block_offsets = NULL;
	ctx->bad_block_alloc = 0;
	ctx->bad_block_count = 0;

	ctx->buffer = malloc(partition->erase_size);
	if (ctx->buffer == NULL) {
		free(ctx);
		return NULL;
	}

	char mtddevname[32];
	sprintf(mtddevname, "/dev/mtd/mtd%d", partition->device_index);
	ctx->fd = open(mtddevname, O_RDWR);
	if (ctx->fd < 0) {
		free(ctx->buffer);
		free(ctx);
		return NULL;
	}

	ctx->partition = partition;
	ctx->stored = 0;
	return ctx;
}

static int bml_over_mtd_write_close(BmlOverMtdWriteContext *ctx)
{
	int r = 0;
	if (close(ctx->fd)) r = -1;
	free(ctx->bad_block_offsets);
	free(ctx->buffer);
	free(ctx);
	return r;
}


#ifdef LOG_TAG
#undef LOG_TAG
#endif

#define LOG_TAG "bml_over_mtd"

#define BLOCK_SIZE    2048
#define SPARE_SIZE    (BLOCK_SIZE >> 5)

#define EXIT_CODE_BAD_BLOCKS 15

static int die(const char *msg, ...) {
	int err = errno;
	va_list args;
	va_start(args, msg);
	char buf[1024];
	vsnprintf(buf, sizeof(buf), msg, args);
	va_end(args);

	if (err != 0) {
		strlcat(buf, ": ", sizeof(buf));
		strlcat(buf, strerror(err), sizeof(buf));
	}

	fprintf(stderr, "%s\n", buf);
	return 1;
}

static unsigned short* CreateEmptyBlockMapping(const MtdPartition* pSrcPart)
{
	size_t srcTotal, srcErase, srcWrite;
	if (mtd_partition_info(pSrcPart, &srcTotal, &srcErase, &srcWrite) != 0)
	{
		fprintf(stderr, "Failed to access partition.\n");
		return NULL;
	}

	int numSrcBlocks = srcTotal/srcErase;

	unsigned short* pMapping = malloc(numSrcBlocks * sizeof(unsigned short));
	if (pMapping == NULL)
	{
		fprintf(stderr, "Failed to allocate block mapping memory.\n");
		return NULL;
	}
	memset(pMapping, 0xFF, numSrcBlocks * sizeof(unsigned short));
	return pMapping;
}

static const unsigned short* CreateBlockMapping(const MtdPartition* pSrcPart, int srcPartStartBlock,
		const MtdPartition *pReservoirPart, int reservoirPartStartBlock)
{
	size_t srcTotal, srcErase, srcWrite;
	if (mtd_partition_info(pSrcPart, &srcTotal, &srcErase, &srcWrite) != 0)
	{
		fprintf(stderr, "Failed to access partition.\n");
		return NULL;
	}

	int numSrcBlocks = srcTotal/srcErase;

	unsigned short* pMapping = malloc(numSrcBlocks * sizeof(unsigned short));
	if (pMapping == NULL)
	{
		fprintf(stderr, "Failed to allocate block mapping memory.\n");
		return NULL;
	}
	memset(pMapping, 0xFF, numSrcBlocks * sizeof(unsigned short));

	size_t total, erase, write;
	if (mtd_partition_info(pReservoirPart, &total, &erase, &write) != 0)
	{
		fprintf(stderr, "Failed to access reservoir partition.\n");
		free(pMapping);
		return NULL;
	}

	if (erase != srcErase || write != srcWrite)
	{
		fprintf(stderr, "Source partition and reservoir partition differ in size properties.\n");
		free(pMapping);
		return NULL;
	}

	printf("Partition info: Total %d, Erase %d, write %d\n", total, erase, write);

	BmlOverMtdReadContext *readctx = bml_over_mtd_read_partition(pReservoirPart);
	if (readctx == NULL)
	{
		fprintf(stderr, "Failed to open reservoir partition for reading.\n");
		free(pMapping);
		return NULL;
	}

	if (total < erase || total > INT_MAX)
	{
		fprintf(stderr, "Unsuitable reservoir partition properties.\n");
		free(pMapping);
		bml_over_mtd_read_close(readctx);
		return NULL;
	}

	int foundMappingTable = 0;

	int currOffset = total; //Offset *behind* the last byte
	while (currOffset > 0)
	{
		currOffset -= erase;
		loff_t pos = lseek64(readctx->fd, currOffset, SEEK_SET);
		int mgbb = ioctl(readctx->fd, MEMGETBADBLOCK, &pos);
		if (mgbb != 0)
		{
			printf("Bad block %d in reservoir area, skipping.\n", currOffset/erase);
			continue;
		}
		ssize_t readBytes = read(readctx->fd, readctx->buffer, erase);
		if (readBytes != (ssize_t)erase)
		{
			fprintf(stderr, "Failed to read good block in reservoir area (%s).\n",
					strerror(errno));
			free(pMapping);
			bml_over_mtd_read_close(readctx);
			return NULL;
		}
		if (readBytes >= 0x2000)
		{
			char* buf = readctx->buffer;
			if (buf[0]=='U' && buf[1]=='P' && buf[2]=='C' && buf[3]=='H')
			{
				printf ("Found mapping block mark at 0x%x (block %d).\n", currOffset, currOffset/erase);

				unsigned short* mappings = (unsigned short*) &buf[0x1000];
				if (mappings[0]==0 && mappings[1]==0xffff)
				{
					printf("Found start of mapping table.\n");
					foundMappingTable = 1;
					//Skip first entry (dummy)
					unsigned short* mappingEntry = mappings + 2;
					while (mappingEntry - mappings < 100
							&& mappingEntry[0] != 0xffff)
					{
						unsigned short rawSrcBlk = mappingEntry[0];
						unsigned short rawDstBlk = mappingEntry[1];

						printf("Found raw block mapping %d -> %d\n", rawSrcBlk,
								rawDstBlk);

						unsigned int srcAbsoluteStartAddress = srcPartStartBlock * erase;
						unsigned int resAbsoluteStartAddress = reservoirPartStartBlock * erase;

						int reservoirLastBlock = reservoirPartStartBlock + numSrcBlocks - 1;
						if (rawDstBlk < reservoirPartStartBlock
								|| rawDstBlk*erase >= resAbsoluteStartAddress+currOffset)
						{
							fprintf(stderr, "Mapped block not within reasonable reservoir area.\n");
							foundMappingTable = 0;
							break;
						}

						int srcLastBlock = srcPartStartBlock + numSrcBlocks - 1;
						if (rawSrcBlk >= srcPartStartBlock && rawSrcBlk <= srcLastBlock)
						{

							unsigned short relSrcBlk = rawSrcBlk - srcPartStartBlock;
							unsigned short relDstBlk = rawDstBlk - reservoirPartStartBlock;
							printf("Partition relative block mapping %d -> %d\n",relSrcBlk, relDstBlk);

							printf("Absolute mapped start addresses 0x%x -> 0x%x\n",
									srcAbsoluteStartAddress+relSrcBlk*erase,
									resAbsoluteStartAddress+relDstBlk*erase);
							printf("Partition relative mapped start addresses 0x%x -> 0x%x\n",
									relSrcBlk*erase, relDstBlk*erase);

							//Set mapping entry. For duplicate entries, later entries replace former ones.
							//*Assumption*: Bad blocks in reservoir area will not be mapped themselves in
							//the mapping table. User partition blocks will not be mapped to bad blocks
							//(only) in the reservoir area. This has to be confirmed on a wider range of
							//devices.
							pMapping[relSrcBlk] = relDstBlk;

						}
						mappingEntry+=2;
					}
					break; //We found the mapping table, no need to search further
				}


			}
		}

	}
	bml_over_mtd_read_close(readctx);

	if (foundMappingTable == 0)
	{
		fprintf(stderr, "Cannot find mapping table in reservoir partition.\n");
		free(pMapping);
		return NULL;
	}

	//Consistency and validity check
	int mappingValid = 1;
	readctx = bml_over_mtd_read_partition(pSrcPart);
	if (readctx == NULL)
	{
		fprintf(stderr, "Cannot open source partition for reading.\n");
		free(pMapping);
		return NULL;
	}
	int currBlock = 0;
	for (;currBlock < numSrcBlocks; ++currBlock)
	{
		loff_t pos = lseek64(readctx->fd, currBlock*erase, SEEK_SET);
		int mgbb = ioctl(readctx->fd, MEMGETBADBLOCK, &pos);
		if (mgbb == 0)
		{
			if (pMapping[currBlock]!=0xffff)
			{
				fprintf(stderr, "Consistency error: Good block has mapping entry %d -> %d\n", currBlock, pMapping[currBlock]);
				mappingValid = 0;
			}
		} else
		{
			//Bad block!
			if (pMapping[currBlock]==0xffff)
			{
				fprintf(stderr, "Consistency error: Bad block has no mapping entry \n");
				mappingValid = 0;
			} else
			{
				BmlOverMtdReadContext* reservoirReadCtx = bml_over_mtd_read_partition(pReservoirPart);
				if (reservoirReadCtx == 0)
				{
					fprintf(stderr, "Reservoir partition cannot be opened for reading in consistency check.\n");
					mappingValid = 0;
				} else
				{
					pos = lseek64(reservoirReadCtx->fd, pMapping[currBlock]*erase, SEEK_SET);
					mgbb = ioctl(reservoirReadCtx->fd, MEMGETBADBLOCK, &pos);
					if (mgbb == 0)
					{
						printf("Bad block has properly mapped reservoir block %d -> %d\n",currBlock, pMapping[currBlock]);
					}
					else
					{
						fprintf(stderr, "Consistency error: Mapped block is bad, too. (%d -> %d)\n",currBlock, pMapping[currBlock]);
						mappingValid = 0;
					}

				}
				bml_over_mtd_read_close(reservoirReadCtx);
			}

		}

	}
	bml_over_mtd_read_close(readctx);


	if (!mappingValid)
	{
		free(pMapping);
		return NULL;
	}

	return pMapping;
}

static void ReleaseBlockMapping(const unsigned short* blockMapping)
{
	free((void*)blockMapping);
}

static int dump_bml_partition(const MtdPartition* pSrcPart, const MtdPartition* pReservoirPart,
		const unsigned short* blockMapping, const char* filename)
{
	int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
	if (fd < 0)
	{
		fprintf(stderr, "error opening %s", filename);
		return -1;
	}
	BmlOverMtdReadContext* pSrcRead = bml_over_mtd_read_partition(pSrcPart);
	if (pSrcRead == NULL)
	{
		close(fd);
		fprintf(stderr, "dump_bml_partition: Error opening src part for reading.\n");
		return -1;
	}

	BmlOverMtdReadContext* pResRead = bml_over_mtd_read_partition(pReservoirPart);
	if (pResRead == NULL)
	{
		close(fd);
		bml_over_mtd_read_close(pSrcRead);
		fprintf(stderr, "dump_bml_partition: Error opening reservoir part for reading.\n");
		return -1;
	}


	int numBlocks = pSrcPart->size / pSrcPart->erase_size;
	int currblock = 0;
	for (;currblock < numBlocks; ++currblock)
	{
		int srcFd = -1;
		if (blockMapping[currblock] == 0xffff)
		{
			//Good block, use src partition
			srcFd = pSrcRead->fd;
			if (lseek64(pSrcRead->fd, currblock*pSrcPart->erase_size, SEEK_SET)==-1)
			{
				close(fd);
				bml_over_mtd_read_close(pSrcRead);
				bml_over_mtd_read_close(pResRead);
				fprintf(stderr, "dump_bml_partition: lseek in src partition failed\n");
				return -1;
			}
		} else
		{
			//Bad block, use mapped block in reservoir partition
			srcFd = pResRead->fd;
			if (lseek64(pResRead->fd, blockMapping[currblock]*pSrcPart->erase_size, SEEK_SET)==-1)
			{
				close(fd);
				bml_over_mtd_read_close(pSrcRead);
				bml_over_mtd_read_close(pResRead);
				fprintf(stderr, "dump_bml_partition: lseek in reservoir partition failed\n");
				return -1;
			}
		}
		size_t blockBytesRead = 0;
		while (blockBytesRead < pSrcPart->erase_size)
		{
			ssize_t len = read(srcFd, pSrcRead->buffer + blockBytesRead,
					pSrcPart->erase_size - blockBytesRead);
			if (len <= 0)
			{
				close(fd);
				bml_over_mtd_read_close(pSrcRead);
				bml_over_mtd_read_close(pResRead);
				fprintf(stderr, "dump_bml_partition: reading partition failed\n");
				return -1;
			}
			blockBytesRead += len;
		}

		size_t blockBytesWritten = 0;
		while (blockBytesWritten < pSrcPart->erase_size)
		{
			ssize_t len = write(fd, pSrcRead->buffer + blockBytesWritten,
					pSrcPart->erase_size - blockBytesWritten);
			if (len <= 0)
			{
				close(fd);
				bml_over_mtd_read_close(pSrcRead);
				bml_over_mtd_read_close(pResRead);
				fprintf(stderr, "dump_bml_partition: writing partition dump file failed\n");
				return -1;
			}
			blockBytesWritten += len;
		}

	}

	bml_over_mtd_read_close(pSrcRead);
	bml_over_mtd_read_close(pResRead);

	if (close(fd)) {
		unlink(filename);
		printf("error closing %s", filename);
		return -1;
	}

	return 0;
}

static ssize_t bml_over_mtd_write_block(int fd, ssize_t erase_size, char* data)
{
	off_t pos = lseek(fd, 0, SEEK_CUR);
	if (pos == (off_t) -1) return -1;

	ssize_t size = erase_size;
	loff_t bpos = pos;
	int ret = ioctl(fd, MEMGETBADBLOCK, &bpos);
	if (ret != 0 && !(ret == -1 && errno == EOPNOTSUPP)) {
		fprintf(stderr,
				"Mapping failure: Trying to write bad block at 0x%08lx (ret %d errno %d)\n",
				pos, ret, errno);
		return -1;
	}

	struct erase_info_user erase_info;
	erase_info.start = pos;
	erase_info.length = size;
	int retry;
	for (retry = 0; retry < 2; ++retry) {
#ifdef RK3X
		if (rk30_zero_out(fd, pos, size) < 0) {
			fprintf(stderr, "mtd: erase failure at 0x%08lx (%s)\n",
					pos, strerror(errno));
			continue;
		}
#else
		if (ioctl(fd, MEMERASE, &erase_info) < 0) {
			fprintf(stderr, "mtd: erase failure at 0x%08lx (%s)\n",
					pos, strerror(errno));
			continue;
		}
#endif
		if (lseek(fd, pos, SEEK_SET) != pos ||
				write(fd, data, size) != size) {
			fprintf(stderr, "mtd: write error at 0x%08lx (%s)\n",
					pos, strerror(errno));
		}

		char verify[size];
		if (lseek(fd, pos, SEEK_SET) != pos ||
				read(fd, verify, size) != size) {
			fprintf(stderr, "mtd: re-read error at 0x%08lx (%s)\n",
					pos, strerror(errno));
			continue;
		}
		if (memcmp(data, verify, size) != 0) {
			fprintf(stderr, "mtd: verification error at 0x%08lx (%s)\n",
					pos, strerror(errno));
			continue;
		}

		if (retry > 0) {
			fprintf(stderr, "mtd: wrote block after %d retries\n", retry);
		}
		fprintf(stderr, "mtd: successfully wrote block at %llx\n", pos);
		return size;  // Success!
	}


	fprintf(stderr, "mtd: Block at %llx could not be properly written.\n", pos);
	// Ran out of space on the device
	errno = ENOSPC;
	return -1;
}

static int flash_bml_partition(const MtdPartition* pSrcPart, const MtdPartition* pReservoirPart,
		const unsigned short* blockMapping, const char* filename)
{
	int fd = open(filename, O_RDONLY);
	if (fd < 0)
	{
		fprintf(stderr, "error opening %s", filename);
		return -1;
	}
	BmlOverMtdWriteContext* pSrcWrite = bml_over_mtd_write_partition(pSrcPart);
	if (pSrcWrite == NULL)
	{
		close(fd);
		fprintf(stderr, "flash_bml_partition: Error opening src part for writing.\n");
		return -1;
	}

#ifdef DUMMY_WRITING
	close(pSrcWrite->fd);
	pSrcWrite->fd = open("/sdcard/srcPartWriteDummy.bin", O_WRONLY|O_CREAT|O_TRUNC, 0666);
#endif

	BmlOverMtdWriteContext* pResWrite = bml_over_mtd_write_partition(pReservoirPart);
	if (pResWrite == NULL)
	{
		close(fd);
		bml_over_mtd_write_close(pSrcWrite);
		fprintf(stderr, "flash_bml_partition: Error opening reservoir part for writing.\n");
		return -1;
	}
#ifdef DUMMY_WRITING
	close(pResWrite->fd);
	pResWrite->fd = open("/sdcard/resPartWriteDummy.bin", O_WRONLY|O_CREAT|O_TRUNC, 0666);
#endif

	struct stat fileStat;
	if (fstat(fd, &fileStat) != 0)
	{
		close(fd);
		bml_over_mtd_write_close(pSrcWrite);
		bml_over_mtd_write_close(pResWrite);
		fprintf(stderr, "flash_bml_partition: Failed to stat source file.\n");
		return -1;

	}
	if (fileStat.st_size > pSrcPart->size)
	{
		close(fd);
		bml_over_mtd_write_close(pSrcWrite);
		bml_over_mtd_write_close(pResWrite);
		fprintf(stderr, "flash_bml_partition: Source file too large for target partition.\n");
		return -1;
	}

	int numBlocks = (fileStat.st_size +  pSrcPart->erase_size - 1) / pSrcPart->erase_size;
	int currblock;
	for (currblock = 0 ;currblock < numBlocks; ++currblock)
	{
		memset(pSrcWrite->buffer, 0xFF, pSrcPart->erase_size);
		size_t blockBytesRead = 0;
		while (blockBytesRead < pSrcPart->erase_size)
		{
			ssize_t len = read(fd, pSrcWrite->buffer + blockBytesRead,
					pSrcPart->erase_size - blockBytesRead);
			if (len < 0)
			{
				close(fd);
				bml_over_mtd_write_close(pSrcWrite);
				bml_over_mtd_write_close(pResWrite);
				fprintf(stderr, "flash_bml_partition: read source file failed\n");
				return -1;
			}
			if (len == 0)
			{
				//End of file
				break;
			}

			blockBytesRead += len;
		}



		int srcFd = -1;
		if (blockMapping[currblock] == 0xffff)
		{
			//Good block, use src partition
			srcFd = pSrcWrite->fd;
			if (lseek64(pSrcWrite->fd, currblock*pSrcPart->erase_size, SEEK_SET)==-1)
			{
				close(fd);
				bml_over_mtd_write_close(pSrcWrite);
				bml_over_mtd_write_close(pResWrite);
				fprintf(stderr, "flash_bml_partition: lseek in src partition failed\n");
				return -1;
			}
		} else
		{
			//Bad block, use mapped block in reservoir partition
			srcFd = pResWrite->fd;
			if (lseek64(pResWrite->fd, blockMapping[currblock]*pSrcPart->erase_size, SEEK_SET)==-1)
			{
				close(fd);
				bml_over_mtd_write_close(pSrcWrite);
				bml_over_mtd_write_close(pResWrite);
				fprintf(stderr, "flash_bml_partition: lseek in reservoir partition failed\n");
				return -1;
			}
		}
		size_t blockBytesWritten = 0;
		while (blockBytesWritten < pSrcPart->erase_size)
		{
#ifdef DUMMY_WRITING
			ssize_t len = write(srcFd, pSrcWrite->buffer + blockBytesWritten,
					pSrcPart->erase_size - blockBytesWritten);
#else
			ssize_t len = bml_over_mtd_write_block(srcFd, pSrcPart->erase_size, pSrcWrite->buffer);
#endif
			if (len <= 0)
			{
				close(fd);
				bml_over_mtd_write_close(pSrcWrite);
				bml_over_mtd_write_close(pResWrite);
				fprintf(stderr, "flash_bml_partition: writing to partition failed\n");
				return -1;
			}
			blockBytesWritten += len;
		}


	}

	bml_over_mtd_write_close(pSrcWrite);
	bml_over_mtd_write_close(pResWrite);

	if (close(fd)) {
		printf("error closing %s", filename);
		return -1;
	}

	return 0;
}

static int scan_partition(const MtdPartition* pPart)
{
	BmlOverMtdReadContext* readCtx = bml_over_mtd_read_partition(pPart);
	if (readCtx == NULL)
	{
		fprintf(stderr, "Failed to open partition for reading.\n");
		return -1;
	}

	int numBadBlocks = 0;
	size_t numBlocks = pPart->size / pPart->erase_size;
	size_t currBlock;
	for (currBlock = 0; currBlock < numBlocks; ++currBlock)
	{

		loff_t pos = currBlock * pPart->erase_size;
		int mgbb = ioctl(readCtx->fd, MEMGETBADBLOCK, &pos);
		if (mgbb != 0)
		{
			printf("Bad block %d at 0x%x.\n", currBlock, (unsigned int)pos);
			numBadBlocks++;
		}
	}

	bml_over_mtd_read_close(readCtx);
	if (numBadBlocks == 0)
	{
		printf("No bad blocks.\n");
		return 0;
	}
	return -1 ;
}

int main(int argc, char **argv)
{
	if (argc != 7 && (argc != 3 || (argc == 3 && strcmp(argv[1],"scan"))!=0)
			&& (argc != 6 || (argc == 6 && strcmp(argv[1],"scan"))!=0))
		return die("Usage: %s dump|flash <partition> <partition_start_block> <reservoirpartition> <reservoir_start_block> <file>\n"
				"E.g. %s dump boot 72 reservoir 2004 file.bin\n"
				"Usage: %s scan <partition> [<partition_start_block> <reservoirpartition> <reservoir_start_block>]\n"
				,argv[0], argv[0], argv[0]);
	int num_partitions = mtd_scan_partitions();
	const MtdPartition *pSrcPart = mtd_find_partition_by_name(argv[2]);
	if (pSrcPart == NULL)
		return die("Cannot find partition %s", argv[2]);

	int scanResult = scan_partition(pSrcPart);

	if (argc == 3 && strcmp(argv[1],"scan")==0)
	{
		return (scanResult == 0 ? 0 : EXIT_CODE_BAD_BLOCKS);
	}

	int retVal = 0;
	const MtdPartition* pReservoirPart = mtd_find_partition_by_name(argv[4]);
	if (pReservoirPart == NULL)
		return die("Cannot find partition %s", argv[4]);

	int srcPartStartBlock = atoi(argv[3]);
	int reservoirPartStartBlock = atoi(argv[5]);
	const unsigned short* pMapping = CreateBlockMapping(pSrcPart, srcPartStartBlock,
			pReservoirPart, reservoirPartStartBlock);

	if (pMapping == NULL && scanResult == 0)
	{
		printf("Generating empty block mapping table for error-free partition.\n");
		pMapping = CreateEmptyBlockMapping(pSrcPart);
	}

	if (argc == 6 && strcmp(argv[1],"scan")==0)
	{
		retVal = (scanResult == 0 ? 0 : EXIT_CODE_BAD_BLOCKS);
	}

	if (pMapping == NULL)
		return die("Failed to create block mapping table");

	if (strcmp(argv[1],"dump")==0)
	{
		retVal = dump_bml_partition(pSrcPart, pReservoirPart, pMapping, argv[6]);
		if (retVal == 0)
			printf("Successfully dumped partition to %s\n", argv[6]);
	}

	if (strcmp(argv[1],"flash")==0)
	{
		retVal = flash_bml_partition(pSrcPart, pReservoirPart, pMapping, argv[6]);
		if (retVal == 0)
			printf("Successfully wrote %s to partition\n", argv[6]);

	}


	ReleaseBlockMapping(pMapping);
	return retVal;
}

