/*
 * MMC-based transactional key-value store
 *
 * Copyright (C) 2010 Google, Inc.
 * Author: Bill he <yuegui.he@amlogic.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 */
#include <amlogic/flash_ts.h>
#include <amlogic/mmc_ts.h>
#include <common.h>
#include <malloc.h>
#include <mmc.h>
#include <partition_table.h>
#include <emmc_partitions.h>
#include <asm/arch/cpu_sdio.h>
#include <asm/arch/sd_emmc.h>
#include <linux/sizes.h>
#include <amlogic/aml_mmc.h>

#define DRV_DESC        	"MMC-based key-value storage"

/* Internal state */
struct mmc_ts_priv {
	struct mutex lock;
	struct mmc *mmc;
	struct partitions *part_info;

	/* chunk size, >= sizeof(struct mmc_ts) */
	size_t chunk;

	int mmc_read_write_unit;

	/* current record offset within mmc partition device */
	loff_t offset;

	/* fts partition offset on*/
	u64 mmc_ts_offset;

	/* fts partition size */
	u64 mmc_ts_size;

	/* mmc dev*/
	int dev;

	/* in-memory copy of mmc content */
	struct flash_ts cache;

	/* temporary buffers
	 *  - one backup for failure rollback
	 *  - another for read-after-write verification
	 */
	struct flash_ts cache_tmp_backup;
	struct flash_ts cache_tmp_verify;
};

static struct mmc_ts_priv *__ts;
static inline void __mmc_ts_put(struct mmc_ts_priv *ts)
{
	mutex_unlock(&ts->lock);
}

static void set_to_default_empty_state(struct mmc_ts_priv *ts)
{
	ts->offset = ts->part_info->size - ts->chunk;
	ts->cache.version = 0;
	ts->cache.len = 1;
	ts->cache.magic = FLASH_TS_MAGIC;
	ts->cache.data[0] = '\0';
}

static struct mmc_ts_priv *__mmc_ts_get(void)
{
	struct mmc_ts_priv *ts = __ts;

	if (likely(ts)) {
		mutex_lock(&ts->lock);
	} else {
		printk(KERN_ERR DRV_NAME ": not initialized yet\n");
	}

	return ts;
}

static char *mmc_ts_find(struct mmc_ts_priv *ts, const char *key, size_t key_len)
{
	char *s = ts->cache.data;
	while (*s) {
		if (!strncmp(s, key, key_len)) {
			if (s[key_len] == '=')
				return s;
		}

		s += strlen(s) + 1;
	}
	return NULL;
}

static inline u32 mmc_ts_check_header(const struct flash_ts *cache)
{
	if (cache->magic == FLASH_TS_MAGIC &&
	    cache->version &&
	    cache->len && cache->len <= sizeof(cache->data) &&
	    /* check correct null-termination */
	    !cache->data[cache->len - 1] &&
	    (cache->len == 1 || !cache->data[cache->len - 2])) {
		/* all is good */
		return cache->version;
	}

	return 0;
}

static int mmc_ts_read(int dev, struct mmc_ts_priv *ts, loff_t off, void *buf, size_t size, u64 part_start_offset)
{
	ulong start_blk;
	struct mmc *mmc = ts->mmc;
	void *addr_byte, *addr = buf, *addr_tmp;
	u64 cnt = 0, sz_byte = 0, n = 0, blk = 0;
	mmc = find_mmc_device(dev);
	if (!mmc) {
		return 1;
	}
	mmc_init(mmc);

	/* blk shift : normal is 9 */
	int blk_shift = 0;
	blk_shift =  ffs(mmc->read_bl_len) - 1;

	/* start blk offset */
	blk = (part_start_offset + off) >> blk_shift;

	/* seziof(ts->cache_tmp_verify) = cnt * ts->chunk + sz_byte */
	cnt = size >> blk_shift;
	sz_byte = size - (cnt << blk_shift);

	/* read cnt* ts->chunk bytes */
	n = blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr);

	/* read sz_byte bytes */
	if ((n == cnt) && (sz_byte != 0)) {
		//printf("sz_byte=%#llx bytes\n",sz_byte);
		addr_tmp = malloc(mmc->read_bl_len);
		addr_byte = (void *)(addr+cnt*(mmc->read_bl_len));
		start_blk = blk+cnt;

		if (addr_tmp == NULL) {
			printf("mmc read: malloc fail\n");
			free(addr);
			return 1;
		}

		if (blk_dread(mmc_get_blk_desc(mmc), start_blk, 1, addr_tmp) != 1) { // read 1 block
			free(addr_tmp);
			printf("mmc read 1 block fail\n");
			return 1;
		}

		memcpy(addr_byte, addr_tmp, sz_byte);
		free(addr_tmp);
	}

	return 0;
}

static int mmc_is_blank(const void *buf, size_t size)
{
	size_t i;
	const unsigned int *data = (const unsigned int *)buf;
	size /= sizeof(data[0]);

	for (i = 0; i < size; i++)
		if (data[i] != 0xffffffff)
			return 0;
	return 1;
}

static int __init mmc_ts_scan(struct mmc_ts_priv *ts, int dev)
{
	struct mmc *mmc = ts->mmc;
	int res;
	loff_t off = 0;
	struct flash_ts tmp_scan_backup;
	u64 mmc_ts_size = ts->mmc_ts_size;
	u64 part_start_offset = ts->mmc_ts_offset;
	void *scan_addr = (void *) &tmp_scan_backup;

	memset(&tmp_scan_backup, 0, sizeof(tmp_scan_backup));

	mmc_init(mmc);

	do {
		/* read FLASH_TS_MAX_DATA_SIZE  data to ts->cache_tmp_verify */
		res = mmc_ts_read(dev, ts, off, scan_addr, sizeof(tmp_scan_backup), part_start_offset);
		if (!res) {
			/* check data struct */
			u32 version = mmc_ts_check_header(scan_addr);
			if (version > 0) {
				if (version > ts->cache.version) {
					memcpy(&ts->cache, scan_addr, sizeof(tmp_scan_backup));
					ts->offset = off;
				}
				break;
			} else if (0 == version && mmc_is_blank(&tmp_scan_backup, sizeof(tmp_scan_backup))) {
				off = (off + ts->mmc->erase_grp_size) & ~(ts->mmc->erase_grp_size - 1);
			} else {
				off += ts->chunk;
			}

		} else {
			off += ts->chunk;
		}

	} while(off < mmc_ts_size) ;/* while done*/

	return res;
}


static int mmc_write(int dev, struct mmc_ts_priv *ts, loff_t off, void *buf, size_t size, u64 part_start_offset)
{
	ulong start_blk;
	struct mmc *mmc = ts->mmc;
	void *addr_byte, *addr_tmp, *addr, *addr_read;
	u64 cnt = 0, sz_byte = 0, n = 0, blk = 0, res;
	struct flash_ts tmp_write_backup, tmp_read_backup;

	/*********init local data struct**************/
	memset(&tmp_write_backup, 0, sizeof(tmp_write_backup));
	memset(&tmp_read_backup, 0, sizeof(tmp_read_backup));
	memcpy(&tmp_write_backup, buf, size);
	addr = (void *) &tmp_write_backup;
	addr_read = (void *) &tmp_read_backup;
	/********************************************/

	mmc = find_mmc_device(dev);
	if (!mmc) {
		return 1;
	}
	mmc_init(mmc);

	/* blk shift : normal is 9 */
	int blk_shift = 0;
	blk_shift =  ffs(mmc->read_bl_len) - 1;

	/* start blk offset */
	blk = (part_start_offset + off) >> blk_shift;

	/* seziof(ts->cache_tmp_verify) = cnt * ts->chunk + sz_byte */
	cnt = size >> blk_shift;
	sz_byte = size - (cnt << blk_shift);

	n = blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr);
	//write sz_byte bytes
	if ((n == cnt) && (sz_byte != 0)) {
		// printf("sz_byte=%#llx bytes\n",sz_byte);
		addr_tmp = malloc(mmc->write_bl_len);
		addr_byte = (void*)(addr+cnt*(mmc->write_bl_len));
		start_blk = blk+cnt;

		if (addr_tmp == NULL) {
			printf("mmc write: malloc fail\n");
			return 1;
		}

		if (blk_dread(mmc_get_blk_desc(mmc), start_blk, 1, addr_tmp) != 1) { // read 1 block
			free(addr_tmp);
			printf("mmc read 1 block fail\n");
			return 1;
		}

		memcpy(addr_tmp, addr_byte, sz_byte);
		if (blk_dwrite(mmc_get_blk_desc(mmc), blk, cnt, addr) != 1) { // write 1 block
			free(addr_tmp);
			printf("mmc write 1 block fail\n");
			return 1;
		}
		free(addr_tmp);
	}

	res = mmc_ts_read(dev, ts, off, addr_read, sizeof(tmp_read_backup), part_start_offset);

	if (!res) {
		if (! memcmp(&tmp_write_backup, &tmp_read_backup, size)) {
			memcpy(&ts->cache, &tmp_write_backup, size);
			printk("key write successfull!\n");
			return 0;
		} else {
			printk("%s:%d error!\n", __func__, __LINE__);
			return -1;
		}

	} else {
		printk("check key failure!\n");
		printk("%s:%d error!\n", __func__, __LINE__);
		return -2;
	}

	return 0;
}

static int mmc_ts_commit(struct mmc_ts_priv *ts)
{
	int res;
	int dev = ts->dev;
	u64 part_start_offset = ts->mmc_ts_offset;

	res = mmc_write(dev,ts, 0, &ts->cache, sizeof(ts->cache), part_start_offset);

	return res;
}

int mmc_ts_set(const char *key, const char *value)
{
	int res;
	char *p;
	struct mmc_ts_priv *ts;
	size_t klen = strlen(key);
	size_t vlen = strlen(value);

	ts = __mmc_ts_get();
	if (unlikely(!ts))
		return -EINVAL;
	/* save current cache contents so we can restore it on failure */
	memcpy(&ts->cache_tmp_backup, &ts->cache, sizeof(ts->cache_tmp_backup));

	p = mmc_ts_find(ts, key, klen);
	if (p) {
		/* we are replacing existing entry,
		 * empty value (vlen == 0) removes entry completely.
		 */
		size_t cur_len = strlen(p) + 1;
		size_t new_len = vlen ? klen + 1 + vlen + 1 : 0;

		if (cur_len != new_len) {
			/* we need to move stuff around */

			if ((ts->cache.len - cur_len) + new_len >
			     sizeof(ts->cache.data))
				goto no_space;

			memmove(p + new_len, p + cur_len,
				ts->cache.len - (p - ts->cache.data + cur_len));

			ts->cache.len = (ts->cache.len - cur_len) + new_len;
		} else if (!strcmp(p + klen + 1, value)) {
			/* skip update if new value is the same as the old one */
			res = 0;
			goto out;
		}

		if (vlen) {
			p += klen + 1;
			memcpy(p, value, vlen);
			p[vlen] = '\0';
		}
	} else {
		size_t len = klen + 1 + vlen + 1;

		/* don't do anything if value is empty */
		if (!vlen) {
			res = 0;
			goto out;
		}

		if (ts->cache.len + len > sizeof(ts->cache.data))
			goto no_space;

		/* add new entry at the end */
		p = ts->cache.data + ts->cache.len - 1;
		memcpy(p, key, klen);
		p += klen;
		*p++ = '=';
		memcpy(p, value, vlen);
		p += vlen;
		*p++ = '\0';
		*p = '\0';
		ts->cache.len += len;
	}
	++ts->cache.version;
	res = mmc_ts_commit(ts);
	if (unlikely(res))
		memcpy(&ts->cache, &ts->cache_tmp_backup, sizeof(ts->cache));

	goto out;

    no_space:
	printk(KERN_WARNING DRV_NAME ": no space left for '%s=%s'\n",
	       key, value);
	res = -ENOSPC;
    out:
	__mmc_ts_put(ts);

	return res;

}

void mmc_ts_get(const char *key, char *value, unsigned int size)
{
	const char *p;
	struct mmc_ts_priv *ts;
	size_t klen = strlen(key);

	BUG_ON(!size);

	*value = '\0';

	ts = __mmc_ts_get();
	if (unlikely(!ts))
		return;

	p = mmc_ts_find(ts, key, klen);
	if (p)
		strlcpy(value, p + klen + 1, size);

	__mmc_ts_put(ts);

}

/* Round-up to the next power-of-2,
 * from "Hacker's Delight" by Henry S. Warren.
 */
static inline u32 clp2(u32 x)
{
	--x;
	x |= x >> 1;
	x |= x >> 2;
	x |= x >> 4;
	x |= x >> 8;
	x |= x >> 16;
	return x + 1;
}

int mmc_ts_init(void)
{
	int res,dev;
	struct mmc *mmc;
	struct mmc_ts_priv *ts;
	struct partitions *part_info = NULL;

	// get dev by name
	dev = find_dev_num_by_partition_name(CONFIG_FLASH_TS_PARTITION);
	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc = find_mmc_device(dev);
	if (!mmc) {
		return 1;
	}

	//init mmc
	mmc_init(mmc);
	//init fts data struct
	ts = malloc(sizeof(*ts));
	if (unlikely(!ts)) {
		res = -ENOMEM;
		printk(KERN_ERR DRV_NAME ": failed to allocate memory\n");
	}

	mutex_init(&ts->lock);
	ts->mmc = mmc;
	ts->mmc_read_write_unit = ts->mmc->read_bl_len;
	ts->chunk = clp2((sizeof(struct flash_ts) + ts->mmc->read_bl_len - 1) &
			~(ts->mmc->read_bl_len - 1));

	/* dev*/
	ts->dev = dev;

	/* get fts part info*/
	part_info = find_mmc_partition_by_name(CONFIG_FLASH_TS_PARTITION);
	if (part_info == NULL) {
		kfree(ts);
		printf("get partition info failed !!\n");
		return -1;
	}

	/* init partiton info to ts data struct*/
	ts->part_info = part_info;
	ts->mmc_ts_offset = ts->part_info->offset;
	ts->mmc_ts_size = ts->part_info->size;

	/* default empty state */
	set_to_default_empty_state(ts);

	/* scan mmc partition for the most recent record */
	res = mmc_ts_scan(ts, dev);
	if (unlikely(res)) {
		goto out_free;
	}

	if (ts->cache.version)
		printk(KERN_INFO DRV_NAME ": v%u loaded from 0x%08llx\n",
		       ts->cache.version, ts->offset);

	res = misc_register(&mmc_ts_miscdev);
	if (unlikely(res)) {
		goto out_free;
	}

	__ts = ts;

	return 0;

out_free:
	kfree(ts);

	return 1;
}
