/*
 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
 *
 * Copyright (C) 2002-2011 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.
 */

#include "yportenv.h"

#include "yaffs_mtdif.h"

#include "linux/mtd/mtd.h"
#include "linux/types.h"
#include "linux/time.h"
#include "linux/mtd/nand.h"
#include "linux/kernel.h"
#include "linux/version.h"
#include "linux/types.h"

#include "yaffs_trace.h"
#include "yaffs_guts.h"
#include "yaffs_linux.h"


#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
#endif


#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0))
#define mtd_erase(m, ei) (m)->erase(m, ei)
#define mtd_write_oob(m, addr, pops) (m)->write_oob(m, addr, pops)
#define mtd_read_oob(m, addr, pops) (m)->read_oob(m, addr, pops)
#define mtd_block_isbad(m, offs) (m)->block_isbad(m, offs)
#define mtd_block_markbad(m, offs) (m)->block_markbad(m, offs)
#endif



int nandmtd_erase_block(struct yaffs_dev *dev, int block_no)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
	u32 addr =
	    ((loff_t) block_no) * dev->param.total_bytes_per_chunk *
	    dev->param.chunks_per_block;
	struct erase_info ei;
	int retval = 0;

	ei.mtd = mtd;
	ei.addr = addr;
	ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block;
	ei.time = 1000;
	ei.retries = 2;
	ei.callback = NULL;
	ei.priv = (u_long) dev;

	retval = mtd_erase(mtd, &ei);

	if (retval == 0)
		return YAFFS_OK;

	return YAFFS_FAIL;
}


static 	int yaffs_mtd_write(struct yaffs_dev *dev, int nand_chunk,
				   const u8 *data, int data_len,
				   const u8 *oob, int oob_len)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
	loff_t addr;
	struct mtd_oob_ops ops;
	int retval;

	addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
	memset(&ops, 0, sizeof(ops));
	ops.mode = MTD_OPS_AUTO_OOB;
	ops.len = (data) ? data_len : 0;
	ops.ooblen = oob_len;
	ops.datbuf = (u8 *)data;
	ops.oobbuf = (u8 *)oob;

	retval = mtd_write_oob(mtd, addr, &ops);
	if (retval) {
		yaffs_trace(YAFFS_TRACE_MTD,
			"write_oob failed, chunk %d, mtd error %d",
			nand_chunk, retval);
	}
	return retval ? YAFFS_FAIL : YAFFS_OK;
}

static int yaffs_mtd_read(struct yaffs_dev *dev, int nand_chunk,
				   u8 *data, int data_len,
				   u8 *oob, int oob_len,
				   enum yaffs_ecc_result *ecc_result)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
	loff_t addr;
	struct mtd_oob_ops ops;
	int retval;

	addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
	memset(&ops, 0, sizeof(ops));
	ops.mode = MTD_OPS_AUTO_OOB;
	ops.len = (data) ? data_len : 0;
	ops.ooblen = oob_len;
	ops.datbuf = data;
	ops.oobbuf = oob;

#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20))
	/* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
	 * help it out with ops.len = ops.ooblen when ops.datbuf == NULL.
	 */
	ops.len = (ops.datbuf) ? ops.len : ops.ooblen;
#endif
	/* Read page and oob using MTD.
	 * Check status and determine ECC result.
	 */
	retval = mtd_read_oob(mtd, addr, &ops);
	if (retval)
		yaffs_trace(YAFFS_TRACE_MTD,
			"read_oob failed, chunk %d, mtd error %d",
			nand_chunk, retval);

	switch (retval) {
	case 0:
		/* no error */
		if(ecc_result)
			*ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
		break;

	case -EUCLEAN:
		/* MTD's ECC fixed the data */
		if(ecc_result)
			*ecc_result = YAFFS_ECC_RESULT_FIXED;
		dev->n_ecc_fixed++;
		break;

	case -EBADMSG:
	default:
		/* MTD's ECC could not fix the data */
		dev->n_ecc_unfixed++;
		if(ecc_result)
			*ecc_result = YAFFS_ECC_RESULT_UNFIXED;
		return YAFFS_FAIL;
	}

	return YAFFS_OK;
}

static 	int yaffs_mtd_erase(struct yaffs_dev *dev, int block_no)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);

	loff_t addr;
	struct erase_info ei;
	int retval = 0;
	u32 block_size;

	block_size = dev->param.total_bytes_per_chunk *
		     dev->param.chunks_per_block;
	addr = ((loff_t) block_no) * block_size;

	ei.mtd = mtd;
	ei.addr = addr;
	ei.len = block_size;
	ei.time = 1000;
	ei.retries = 2;
	ei.callback = NULL;
	ei.priv = (u_long) dev;

	retval = mtd_erase(mtd, &ei);

	if (retval == 0)
		return YAFFS_OK;

	return YAFFS_FAIL;
}

static int yaffs_mtd_mark_bad(struct yaffs_dev *dev, int block_no)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
	int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk;
	int retval;

	yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", block_no);

	retval = mtd_block_markbad(mtd, (loff_t) blocksize * block_no);
	return (retval) ? YAFFS_FAIL : YAFFS_OK;
}

static int yaffs_mtd_check_bad(struct yaffs_dev *dev, int block_no)
{
	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
	int blocksize = dev->param.chunks_per_block * dev->param.total_bytes_per_chunk;
	int retval;

	yaffs_trace(YAFFS_TRACE_TRACING, "checking block %d bad", block_no);

	retval = mtd_block_isbad(mtd, (loff_t) blocksize * block_no);
	if (retval) {
		yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "block %d is bad", block_no);
	}
	return (retval) ? YAFFS_FAIL : YAFFS_OK;
}

static int yaffs_mtd_initialise(struct yaffs_dev *dev)
{
	return YAFFS_OK;
}

static int yaffs_mtd_deinitialise(struct yaffs_dev *dev)
{
	return YAFFS_OK;
}


void yaffs_mtd_drv_install(struct yaffs_dev *dev)
{
	struct yaffs_driver *drv = &dev->drv;

	drv->drv_write_chunk_fn = yaffs_mtd_write;
	drv->drv_read_chunk_fn = yaffs_mtd_read;
	drv->drv_erase_fn = yaffs_mtd_erase;
	drv->drv_mark_bad_fn = yaffs_mtd_mark_bad;
	drv->drv_check_bad_fn = yaffs_mtd_check_bad;
	drv->drv_initialise_fn = yaffs_mtd_initialise;
	drv->drv_deinitialise_fn = yaffs_mtd_deinitialise;
}


struct mtd_info * yaffs_get_mtd_device(dev_t sdev)
{
	struct mtd_info *mtd;

	mtd = yaffs_get_mtd_device(sdev);

	/* Check it's an mtd device..... */
	if (MAJOR(sdev) != MTD_BLOCK_MAJOR)
		return NULL;	/* This isn't an mtd device */

	/* Check it's NAND */
	if (mtd->type != MTD_NANDFLASH) {
		yaffs_trace(YAFFS_TRACE_ALWAYS,
			"yaffs: MTD device is not NAND it's type %d",
			mtd->type);
		return NULL;
	}

	yaffs_trace(YAFFS_TRACE_OS, " %s %d", WRITE_SIZE_STR, WRITE_SIZE(mtd));
	yaffs_trace(YAFFS_TRACE_OS, " oobsize %d", mtd->oobsize);
	yaffs_trace(YAFFS_TRACE_OS, " erasesize %d", mtd->erasesize);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
	yaffs_trace(YAFFS_TRACE_OS, " size %u", mtd->size);
#else
	yaffs_trace(YAFFS_TRACE_OS, " size %lld", mtd->size);
#endif

	return mtd;
}

int yaffs_verify_mtd(struct mtd_info *mtd, int yaffs_version, int inband_tags)
{
	if (yaffs_version == 2) {
		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
		     mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
		    !inband_tags) {
			yaffs_trace(YAFFS_TRACE_ALWAYS,
				"MTD device does not have the right page sizes"
			);
			return -1;
		}
	} else {
		if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK ||
		    mtd->oobsize != YAFFS_BYTES_PER_SPARE) {
			yaffs_trace(YAFFS_TRACE_ALWAYS,
				"MTD device does not support have the right page sizes"
			);
			return -1;
		}
	}

	return 0;
}


void yaffs_put_mtd_device(struct mtd_info *mtd)
{
	if(mtd)
		put_mtd_device(mtd);
}
