/*
 * Copyright (C) 2008 Nokia Corporation
 *
 * 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 program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 * the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Author: Artem Bityutskiy
 *
 * UBI scanning library.
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#include <mtd_swab.h>
#include <mtd/ubi-media.h>
#include <mtd/mtd-user.h>
#include <libmtd.h>
#include <libscan.h>
#include "common.h"
#include "crc32.h"

#define PROGRAM_NAME "libscan"

static int all_ff(const void *buf, int len)
{
	int i;
	const uint8_t *p = buf;

	for (i = 0; i < len; i++)
		if (p[i] != 0xFF)
			return 0;
	return 1;
}

int ubi_scan(struct mtd_dev_info *mtd, int fd, struct ubi_scan_info **info,
	     int verbose)
{
	int eb, v = (verbose == 2), pr = (verbose == 1);
	struct ubi_scan_info *si;
	unsigned long long sum = 0;

	si = calloc(1, sizeof(struct ubi_scan_info));
	if (!si)
		return sys_errmsg("cannot allocate %zd bytes of memory",
				  sizeof(struct ubi_scan_info));

	si->ec = calloc(mtd->eb_cnt, sizeof(uint32_t));
	if (!si->ec) {
		sys_errmsg("cannot allocate %zd bytes of memory",
			   sizeof(struct ubi_scan_info));
		goto out_si;
	}

	si->vid_hdr_offs = si->data_offs = -1;

	verbose(v, "start scanning eraseblocks 0-%d", mtd->eb_cnt);
	for (eb = 0; eb < mtd->eb_cnt; eb++) {
		int ret;
		uint32_t crc;
		struct ubi_ec_hdr hdr;
		unsigned long long ec;

		if (v) {
			normsg_cont("scanning eraseblock %d", eb);
			fflush(stdout);
		}
		if (pr) {
			printf("\r" PROGRAM_NAME ": scanning eraseblock %d -- %2lld %% complete  ",
			       eb, (long long)(eb + 1) * 100 / mtd->eb_cnt);
			fflush(stdout);
		}

		ret = mtd_is_bad(mtd, fd, eb);
		if (ret == -1)
			goto out_ec;
		if (ret) {
			si->bad_cnt += 1;
			si->ec[eb] = EB_BAD;
			if (v)
				printf(": bad\n");
			continue;
		}

		ret = mtd_read(mtd, fd, eb, 0, &hdr, sizeof(struct ubi_ec_hdr));
		if (ret < 0)
			goto out_ec;

		/* Check the EC header */
		if (be32_to_cpu(hdr.magic) != UBI_EC_HDR_MAGIC) {
			if (all_ff(&hdr, sizeof(struct ubi_ec_hdr))) {
				si->empty_cnt += 1;
				si->ec[eb] = EB_EMPTY;
				if (v)
					printf(": empty\n");
			} else {
				si->alien_cnt += 1;
				si->ec[eb] = EB_ALIEN;
				if (v)
					printf(": alien\n");
			}
			continue;
		}

		crc = crc32(UBI_CRC32_INIT, &hdr, UBI_EC_HDR_SIZE_CRC);
		if (be32_to_cpu(hdr.hdr_crc) != crc) {
			si->corrupted_cnt += 1;
			si->ec[eb] = EB_CORRUPTED;
			if (v)
				printf(": bad CRC %#08x, should be %#08x\n",
				       crc, be32_to_cpu(hdr.hdr_crc));
			continue;
		}

		ec = be64_to_cpu(hdr.ec);
		if (ec > EC_MAX) {
			if (pr)
				printf("\n");
			errmsg("erase counter in EB %d is %llu, while this "
			       "program expects them to be less than %u",
			       eb, ec, EC_MAX);
			goto out_ec;
		}

		if (si->vid_hdr_offs == -1) {
			si->vid_hdr_offs = be32_to_cpu(hdr.vid_hdr_offset);
			si->data_offs = be32_to_cpu(hdr.data_offset);
			if (si->data_offs % mtd->min_io_size) {
				if (pr)
					printf("\n");
				if (v)
					printf(": corrupted because of the below\n");
				warnmsg("bad data offset %d at eraseblock %d (n"
					"of multiple of min. I/O unit size %d)",
					si->data_offs, eb, mtd->min_io_size);
				warnmsg("treat eraseblock %d as corrupted", eb);
				si->corrupted_cnt += 1;
				si->ec[eb] = EB_CORRUPTED;
				continue;

			}
		} else {
			if ((int)be32_to_cpu(hdr.vid_hdr_offset) != si->vid_hdr_offs) {
				if (pr)
					printf("\n");
				if (v)
					printf(": corrupted because of the below\n");
				warnmsg("inconsistent VID header offset: was "
					"%d, but is %d in eraseblock %d",
					si->vid_hdr_offs,
					be32_to_cpu(hdr.vid_hdr_offset), eb);
				warnmsg("treat eraseblock %d as corrupted", eb);
				si->corrupted_cnt += 1;
				si->ec[eb] = EB_CORRUPTED;
				continue;
			}
			if ((int)be32_to_cpu(hdr.data_offset) != si->data_offs) {
				if (pr)
					printf("\n");
				if (v)
					printf(": corrupted because of the below\n");
				warnmsg("inconsistent data offset: was %d, but"
					" is %d in eraseblock %d",
					si->data_offs,
					be32_to_cpu(hdr.data_offset), eb);
				warnmsg("treat eraseblock %d as corrupted", eb);
				si->corrupted_cnt += 1;
				si->ec[eb] = EB_CORRUPTED;
				continue;
			}
		}

		si->ok_cnt += 1;
		si->ec[eb] = ec;
		if (v)
			printf(": OK, erase counter %u\n", si->ec[eb]);
	}

	if (si->ok_cnt != 0) {
		/* Calculate mean erase counter */
		for (eb = 0; eb < mtd->eb_cnt; eb++) {
			if (si->ec[eb] > EC_MAX)
				continue;
			sum += si->ec[eb];
		}
		si->mean_ec = sum / si->ok_cnt;
	}

	si->good_cnt = mtd->eb_cnt - si->bad_cnt;
	verbose(v, "finished, mean EC %lld, %d OK, %d corrupted, %d empty, %d "
		"alien, bad %d", si->mean_ec, si->ok_cnt, si->corrupted_cnt,
		si->empty_cnt, si->alien_cnt, si->bad_cnt);

	*info = si;
	if (pr)
		printf("\n");
	return 0;

out_ec:
	free(si->ec);
out_si:
	free(si);
	*info = NULL;
	return -1;
}

void ubi_scan_free(struct ubi_scan_info *si)
{
	free(si->ec);
	free(si);
}
