/*
 * rfdformat.c
 *
 * Copyright (C) 2005 Sean Young <sean@mess.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This is very easy: just erase all the blocks and put the magic at
 * the beginning of each block.
 */

#define _XOPEN_SOURCE 500 /* For pread/pwrite */

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <getopt.h>

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

#define PROGRAM "rfdformat"
#define VERSION "$Revision 1.0 $"

void display_help(void)
{
	printf("Usage: " PROGRAM " [OPTIONS] MTD-device\n"
			"Formats NOR flash for resident flash disk\n"
			"\n"
			"-h         --help               display this help and exit\n"
			"-V         --version            output version information and exit\n");
	exit(0);
}

void display_version(void)
{
	printf(PROGRAM " " VERSION "\n"
			"\n"
			"This is free software; see the source for copying conditions.  There is NO\n"
			"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");

	exit(0);
}

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

	for (;;) {
		int option_index = 0;
		static const char *short_options = "hV";
		static const struct option long_options[] = {
			{ "help", no_argument, 0, 'h' },
			{ "version", no_argument, 0, 'V', },
			{ NULL, 0, 0, 0 }
		};

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

		switch (c) {
			case 'h':
				display_help();
				break;
			case 'V':
				display_version();
				break;
			case '?':
				error = 1;
				break;
		}
	}

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

	*mtd_filename = argv[optind];
}

int main(int argc, char *argv[])
{
	static const uint8_t magic[] = { 0x93, 0x91 };
	int fd, block_count, i;
	struct mtd_info_user mtd_info;
	char buf[512];
	const char *mtd_filename;

	process_options(argc, argv, &mtd_filename);

	fd = open(mtd_filename, O_RDWR);
	if (fd == -1) {
		perror(mtd_filename);
		return 1;
	}

	if (ioctl(fd, MEMGETINFO, &mtd_info)) {
		perror(mtd_filename);
		close(fd);
		return 1;
	}

	if (mtd_info.type != MTD_NORFLASH) {
		fprintf(stderr, "%s: not NOR flash\n", mtd_filename);
		close(fd);
		return 2;
	}

	if (mtd_info.size > 32*1024*1024) {
		fprintf(stderr, "%s: flash larger than 32MiB not supported\n",
				mtd_filename);
		close(fd);
		return 2;
	}

	block_count = mtd_info.size / mtd_info.erasesize;

	if (block_count < 2) {
		fprintf(stderr, "%s: at least two erase units required\n",
				mtd_filename);
		close(fd);
		return 2;
	}

	for (i=0; i<block_count; i++) {
		struct erase_info_user erase_info;

		erase_info.start = i * mtd_info.erasesize;
		erase_info.length = mtd_info.erasesize;

		if (ioctl(fd, MEMERASE, &erase_info) != 0) {
			snprintf(buf, sizeof(buf), "%s: erase", mtd_filename);
			perror(buf);
			close(fd);
			return 2;
		}

		if (pwrite(fd, magic, sizeof(magic), i * mtd_info.erasesize)
				!= sizeof(magic)) {
			snprintf(buf, sizeof(buf), "%s: write", mtd_filename);
			perror(buf);
			close(fd);
			return 2;
		}
	}

	close(fd);

	return 0;
}
