/*
 *  nanddump.c
 *
 *  Copyright (C) 2000 David Woodhouse (dwmw2@infradead.org)
 *                     Steven J. Hill (sjhill@realitydiluted.com)
 *
 * 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.
 *
 *  Overview:
 *   This utility dumps the contents of raw NAND chips or NAND
 *   chips contained in DoC devices.
 */

#define _GNU_SOURCE
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <asm/types.h>
#include <mtd/mtd-user.h>

#define PROGRAM "nanddump"
#define VERSION "$Revision: 1.29 $"

static struct nand_oobinfo none_oobinfo = {
	.useecc = MTD_NANDECC_OFF,
};

static void display_help (void)
{
	printf(
"Usage: nanddump [OPTIONS] MTD-device\n"
"Dumps the contents of a nand mtd partition.\n"
"\n"
"           --help               Display this help and exit\n"
"           --version            Output version information and exit\n"
"-f file    --file=file          Dump to file\n"
"-i         --ignoreerrors       Ignore errors\n"
"-l length  --length=length      Length\n"
"-n         --noecc              Read without error correction\n"
"-o         --omitoob            Omit oob data\n"
"-b         --omitbad            Omit bad blocks from the dump\n"
"-p         --prettyprint        Print nice (hexdump)\n"
"-q         --quiet              Don't display progress and status messages\n"
"-s addr    --startaddress=addr  Start address\n"
"-e         --omitempty          Omit empty pages\n"
	);
	exit(EXIT_SUCCESS);
}

static void display_version (void)
{
	printf(PROGRAM " " VERSION "\n"
			"\n"
			PROGRAM " comes with NO WARRANTY\n"
			"to the extent permitted by law.\n"
			"\n"
			"You may redistribute copies of " PROGRAM "\n"
			"under the terms of the GNU General Public Licence.\n"
			"See the file `COPYING' for more information.\n");
	exit(EXIT_SUCCESS);
}

// Option variables

static bool		ignoreerrors = false;	// ignore errors
static bool		pretty_print = false;	// print nice in ascii
static bool		noecc = false;		// don't error correct
static bool		omitoob = false;	// omit oob data
static unsigned long	start_addr;		// start address
static unsigned long	length;			// dump length
static const char	*mtddev;		// mtd device name
static const char	*dumpfile;		// dump file name
static bool		omitbad = false;
static bool		quiet = false;		// suppress diagnostic output
static bool		omitempty = false;      // don't output empty pages

static void process_options (int argc, char * const argv[])
{
	int error = 0;

	for (;;) {
		int option_index = 0;
		static const char *short_options = "bs:f:il:opqne";
		static const struct option long_options[] = {
			{"help", no_argument, 0, 0},
			{"version", no_argument, 0, 0},
			{"file", required_argument, 0, 'f'},
			{"ignoreerrors", no_argument, 0, 'i'},
			{"prettyprint", no_argument, 0, 'p'},
			{"omitoob", no_argument, 0, 'o'},
			{"omitbad", no_argument, 0, 'b'},
			{"startaddress", required_argument, 0, 's'},
			{"length", required_argument, 0, 'l'},
			{"noecc", no_argument, 0, 'n'},
			{"quiet", no_argument, 0, 'q'},
			{"omitempty", no_argument, 0, 'e'},
			{0, 0, 0, 0},
		};

		int c = getopt_long(argc, argv, short_options,
				long_options, &option_index);
		if (c == EOF) {
			break;
		}

		switch (c) {
			case 0:
				switch (option_index) {
					case 0:
						display_help();
						break;
					case 1:
						display_version();
						break;
				}
				break;
			case 'b':
				omitbad = true;
				break;
			case 's':
				start_addr = strtol(optarg, NULL, 0);
				break;
			case 'f':
				if (!(dumpfile = strdup(optarg))) {
					perror("stddup");
					exit(EXIT_FAILURE);
				}
				break;
			case 'i':
				ignoreerrors = true;
				break;
			case 'l':
				length = strtol(optarg, NULL, 0);
				break;
			case 'o':
				omitoob = true;
				break;
			case 'p':
				pretty_print = true;
				break;
			case 'q':
				quiet = true;
				break;
			case 'n':
				noecc = true;
				break;
			case 'e':
				omitempty = true;
				break;
			case '?':
				error++;
				break;
		}
	}

	if (quiet && pretty_print) {
		fprintf(stderr, "The quiet and pretty print options are mutually-\n"
				"exclusive. Choose one or the other.\n");
		exit(EXIT_FAILURE);
	}

	if ((argc - optind) != 1 || error)
		display_help ();

	mtddev = argv[optind];
}

/*
 * Main program
 */
int main(int argc, char * const argv[])
{
	unsigned long ofs, end_addr = 0;
	unsigned long long blockstart = 1;
	int ret, i, fd, ofd = 0, bs, badblock = 0;
	struct mtd_oob_buf oob;
	mtd_info_t meminfo;
	char pretty_buf[80];
	int oobinfochanged = 0 ;
	struct nand_oobinfo old_oobinfo;
	struct mtd_ecc_stats stat1, stat2;
	bool eccstats = false;
	bool isempty;
	unsigned char *readbuf = NULL, *oobbuf = NULL;

	process_options(argc, argv);

	/* Open MTD device */
	if ((fd = open(mtddev, O_RDONLY)) == -1) {
		perror(mtddev);
		exit (EXIT_FAILURE);
	}

	/* Fill in MTD device capability structure */
	if (ioctl(fd, MEMGETINFO, &meminfo) != 0) {
		perror("MEMGETINFO");
		close(fd);
		exit (EXIT_FAILURE);
	}

	/* Allocate buffers */
	oobbuf = malloc(sizeof(oobbuf) * meminfo.oobsize);
	readbuf = malloc(sizeof(readbuf) * meminfo.writesize);

	if (oobbuf == NULL || readbuf == NULL)
		goto closeall;

	/* Fill in oob info */
	oob.start = 0;
	oob.length = meminfo.oobsize;
	oob.ptr = oobbuf;

	if (noecc)  {
		ret = ioctl(fd, MTDFILEMODE, (void *) MTD_MODE_RAW);
		if (ret == 0) {
			oobinfochanged = 2;
		} else {
			switch (errno) {
			case ENOTTY:
				if (ioctl (fd, MEMGETOOBSEL, &old_oobinfo) != 0) {
					perror ("MEMGETOOBSEL");
					goto closeall;
				}
				if (ioctl (fd, MEMSETOOBSEL, &none_oobinfo) != 0) {
					perror ("MEMSETOOBSEL");
					goto closeall;
				}
				oobinfochanged = 1;
				break;
			default:
				perror ("MTDFILEMODE");
				goto closeall;
			}
		}
	} else {

		/* check if we can read ecc stats */
		if (!ioctl(fd, ECCGETSTATS, &stat1)) {
			eccstats = true;
			if (!quiet) {
				fprintf(stderr, "ECC failed: %d\n", stat1.failed);
				fprintf(stderr, "ECC corrected: %d\n", stat1.corrected);    
				fprintf(stderr, "Number of bad blocks: %d\n", stat1.badblocks);    
				fprintf(stderr, "Number of bbt blocks: %d\n", stat1.bbtblocks);    
			}
		} else
			perror("No ECC status information available");
	}

	/* Open output file for writing. If file name is "-", write to standard
	 * output. */
	if (!dumpfile) {
		ofd = STDOUT_FILENO;
	} else if ((ofd = open(dumpfile, O_WRONLY | O_TRUNC | O_CREAT, 0644))== -1) {
		perror (dumpfile);
		goto closeall;
	}

	/* Initialize start/end addresses and block size */
	if (length)
		end_addr = start_addr + length;
	if (!length || end_addr > meminfo.size)
		end_addr = meminfo.size;

	bs = meminfo.writesize;

	/* Print informative message */

	if (!quiet) {
		fprintf(stderr, "Block size %u, page size %u, OOB size %u\n",
				meminfo.erasesize, meminfo.writesize, meminfo.oobsize);
		fprintf(stderr,
				"Dumping data starting at 0x%08x and ending at 0x%08x...\n",
				(unsigned int) start_addr, (unsigned int) end_addr);
	}
	/* Dump the flash contents */
	for (ofs = start_addr; ofs < end_addr ; ofs+=bs) {

		// new eraseblock , check for bad block
		if (blockstart != (ofs & (~meminfo.erasesize + 1))) {
			blockstart = ofs & (~meminfo.erasesize + 1);
			if ((badblock = ioctl(fd, MEMGETBADBLOCK, &blockstart)) < 0) {
				perror("ioctl(MEMGETBADBLOCK)");
				goto closeall;
			}
		}

		if (badblock) {
			if (omitbad)
				continue;
			memset (readbuf, 0xff, bs);
		} else {
			/* Read page data and exit on failure */
			if (pread(fd, readbuf, bs, ofs) != bs) {
				perror("pread");
				goto closeall;
			}
		}

		/* ECC stats available ? */
		if (eccstats) {
			if (ioctl(fd, ECCGETSTATS, &stat2)) {
				perror("ioctl(ECCGETSTATS)");
				goto closeall;
			}
			if (stat1.failed != stat2.failed)
				fprintf(stderr, "ECC: %d uncorrectable bitflip(s)"
						" at offset 0x%08lx\n",
						stat2.failed - stat1.failed, ofs);
			if (stat1.corrected != stat2.corrected)
				fprintf(stderr, "ECC: %d corrected bitflip(s) at"
						" offset 0x%08lx\n",
						stat2.corrected - stat1.corrected, ofs);
			stat1 = stat2;
		}

		if (omitempty) {
			isempty = true;
			for (i = 0; i < bs; i++) {
				if (readbuf[i] != 0xff) {
					isempty = false;
					break;
				}
			}

			if (isempty) {
				if (!quiet)
					fprintf(stderr, "Skipping empty page at offset 0x%08lx\n", ofs);

				continue;
        	}
        }

		/* Write out page data */
		if (pretty_print) {
			for (i = 0; i < bs; i += 16) {
				sprintf(pretty_buf,
						"0x%08x: %02x %02x %02x %02x %02x %02x %02x "
						"%02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
						(unsigned int) (ofs + i),  readbuf[i],
						readbuf[i+1], readbuf[i+2],
						readbuf[i+3], readbuf[i+4],
						readbuf[i+5], readbuf[i+6],
						readbuf[i+7], readbuf[i+8],
						readbuf[i+9], readbuf[i+10],
						readbuf[i+11], readbuf[i+12],
						readbuf[i+13], readbuf[i+14],
						readbuf[i+15]);
				write(ofd, pretty_buf, 60);
			}
		} else
			write(ofd, readbuf, bs);



		if (omitoob)
			continue;

		if (badblock) {
			memset (readbuf, 0xff, meminfo.oobsize);
		} else {
			/* Read OOB data and exit on failure */
			oob.start = ofs;
			if (ioctl(fd, MEMREADOOB, &oob) != 0) {
				perror("ioctl(MEMREADOOB)");
				goto closeall;
			}
		}

		/* Write out OOB data */
		if (pretty_print) {
			if (meminfo.oobsize < 16) {
				sprintf(pretty_buf, "  OOB Data: %02x %02x %02x %02x %02x %02x "
						"%02x %02x\n",
						oobbuf[0], oobbuf[1], oobbuf[2],
						oobbuf[3], oobbuf[4], oobbuf[5],
						oobbuf[6], oobbuf[7]);
				write(ofd, pretty_buf, 48);
				continue;
			}

			for (i = 0; i < meminfo.oobsize; i += 16) {
				sprintf(pretty_buf, "  OOB Data: %02x %02x %02x %02x %02x %02x "
						"%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
						oobbuf[i], oobbuf[i+1], oobbuf[i+2],
						oobbuf[i+3], oobbuf[i+4], oobbuf[i+5],
						oobbuf[i+6], oobbuf[i+7], oobbuf[i+8],
						oobbuf[i+9], oobbuf[i+10], oobbuf[i+11],
						oobbuf[i+12], oobbuf[i+13], oobbuf[i+14],
						oobbuf[i+15]);
				write(ofd, pretty_buf, 60);
			}
		} else
			write(ofd, oobbuf, meminfo.oobsize);
	}

	/* reset oobinfo */
	if (oobinfochanged == 1) {
		if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0) {
			perror ("MEMSETOOBSEL");
			goto closeall;
		}
	}
	/* Close the output file and MTD device, free memory */
	close(fd);
	close(ofd);
	free(oobbuf);
	free(readbuf);

	/* Exit happy */
	return EXIT_SUCCESS;

closeall:
	/* The new mode change is per file descriptor ! */
	if (oobinfochanged == 1) {
		if (ioctl (fd, MEMSETOOBSEL, &old_oobinfo) != 0)  {
			perror ("MEMSETOOBSEL");
		}
	}
	close(fd);
	close(ofd);
	free(oobbuf);
	free(readbuf);
	exit(EXIT_FAILURE);
}
