// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright © 2009 - Maxim Levitsky
 * SmartMedia/xD translation layer
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/hdreg.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/sysfs.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/mtd/nand-ecc-sw-hamming.h>
#include "nand/raw/sm_common.h"
#include "sm_ftl.h"



static struct workqueue_struct *cache_flush_workqueue;

static int cache_timeout = 1000;
module_param(cache_timeout, int, S_IRUGO);
MODULE_PARM_DESC(cache_timeout,
	"Timeout (in ms) for cache flush (1000 ms default");

static int debug;
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level (0-2)");


/* ------------------- sysfs attributes ---------------------------------- */
struct sm_sysfs_attribute {
	struct device_attribute dev_attr;
	char *data;
	int len;
};

static ssize_t sm_attr_show(struct device *dev, struct device_attribute *attr,
		     char *buf)
{
	struct sm_sysfs_attribute *sm_attr =
		container_of(attr, struct sm_sysfs_attribute, dev_attr);

	strncpy(buf, sm_attr->data, sm_attr->len);
	return sm_attr->len;
}


#define NUM_ATTRIBUTES 1
#define SM_CIS_VENDOR_OFFSET 0x59
static struct attribute_group *sm_create_sysfs_attributes(struct sm_ftl *ftl)
{
	struct attribute_group *attr_group;
	struct attribute **attributes;
	struct sm_sysfs_attribute *vendor_attribute;
	char *vendor;

	vendor = kstrndup(ftl->cis_buffer + SM_CIS_VENDOR_OFFSET,
			  SM_SMALL_PAGE - SM_CIS_VENDOR_OFFSET, GFP_KERNEL);
	if (!vendor)
		goto error1;

	/* Initialize sysfs attributes */
	vendor_attribute =
		kzalloc(sizeof(struct sm_sysfs_attribute), GFP_KERNEL);
	if (!vendor_attribute)
		goto error2;

	sysfs_attr_init(&vendor_attribute->dev_attr.attr);

	vendor_attribute->data = vendor;
	vendor_attribute->len = strlen(vendor);
	vendor_attribute->dev_attr.attr.name = "vendor";
	vendor_attribute->dev_attr.attr.mode = S_IRUGO;
	vendor_attribute->dev_attr.show = sm_attr_show;


	/* Create array of pointers to the attributes */
	attributes = kcalloc(NUM_ATTRIBUTES + 1, sizeof(struct attribute *),
								GFP_KERNEL);
	if (!attributes)
		goto error3;
	attributes[0] = &vendor_attribute->dev_attr.attr;

	/* Finally create the attribute group */
	attr_group = kzalloc(sizeof(struct attribute_group), GFP_KERNEL);
	if (!attr_group)
		goto error4;
	attr_group->attrs = attributes;
	return attr_group;
error4:
	kfree(attributes);
error3:
	kfree(vendor_attribute);
error2:
	kfree(vendor);
error1:
	return NULL;
}

static void sm_delete_sysfs_attributes(struct sm_ftl *ftl)
{
	struct attribute **attributes = ftl->disk_attributes->attrs;
	int i;

	for (i = 0; attributes[i] ; i++) {

		struct device_attribute *dev_attr = container_of(attributes[i],
			struct device_attribute, attr);

		struct sm_sysfs_attribute *sm_attr =
			container_of(dev_attr,
				struct sm_sysfs_attribute, dev_attr);

		kfree(sm_attr->data);
		kfree(sm_attr);
	}

	kfree(ftl->disk_attributes->attrs);
	kfree(ftl->disk_attributes);
}


/* ----------------------- oob helpers -------------------------------------- */

static int sm_get_lba(uint8_t *lba)
{
	/* check fixed bits */
	if ((lba[0] & 0xF8) != 0x10)
		return -2;

	/* check parity - endianness doesn't matter */
	if (hweight16(*(uint16_t *)lba) & 1)
		return -2;

	return (lba[1] >> 1) | ((lba[0] & 0x07) << 7);
}


/*
 * Read LBA associated with block
 * returns -1, if block is erased
 * returns -2 if error happens
 */
static int sm_read_lba(struct sm_oob *oob)
{
	static const uint32_t erased_pattern[4] = {
		0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };

	uint16_t lba_test;
	int lba;

	/* First test for erased block */
	if (!memcmp(oob, erased_pattern, SM_OOB_SIZE))
		return -1;

	/* Now check is both copies of the LBA differ too much */
	lba_test = *(uint16_t *)oob->lba_copy1 ^ *(uint16_t*)oob->lba_copy2;
	if (lba_test && !is_power_of_2(lba_test))
		return -2;

	/* And read it */
	lba = sm_get_lba(oob->lba_copy1);

	if (lba == -2)
		lba = sm_get_lba(oob->lba_copy2);

	return lba;
}

static void sm_write_lba(struct sm_oob *oob, uint16_t lba)
{
	uint8_t tmp[2];

	WARN_ON(lba >= 1000);

	tmp[0] = 0x10 | ((lba >> 7) & 0x07);
	tmp[1] = (lba << 1) & 0xFF;

	if (hweight16(*(uint16_t *)tmp) & 0x01)
		tmp[1] |= 1;

	oob->lba_copy1[0] = oob->lba_copy2[0] = tmp[0];
	oob->lba_copy1[1] = oob->lba_copy2[1] = tmp[1];
}


/* Make offset from parts */
static loff_t sm_mkoffset(struct sm_ftl *ftl, int zone, int block, int boffset)
{
	WARN_ON(boffset & (SM_SECTOR_SIZE - 1));
	WARN_ON(zone < 0 || zone >= ftl->zone_count);
	WARN_ON(block >= ftl->zone_size);
	WARN_ON(boffset >= ftl->block_size);

	if (block == -1)
		return -1;

	return (zone * SM_MAX_ZONE_SIZE + block) * ftl->block_size + boffset;
}

/* Breaks offset into parts */
static void sm_break_offset(struct sm_ftl *ftl, loff_t loffset,
			    int *zone, int *block, int *boffset)
{
	u64 offset = loffset;
	*boffset = do_div(offset, ftl->block_size);
	*block = do_div(offset, ftl->max_lba);
	*zone = offset >= ftl->zone_count ? -1 : offset;
}

/* ---------------------- low level IO ------------------------------------- */

static int sm_correct_sector(uint8_t *buffer, struct sm_oob *oob)
{
	bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
	uint8_t ecc[3];

	ecc_sw_hamming_calculate(buffer, SM_SMALL_PAGE, ecc, sm_order);
	if (ecc_sw_hamming_correct(buffer, ecc, oob->ecc1, SM_SMALL_PAGE,
				   sm_order) < 0)
		return -EIO;

	buffer += SM_SMALL_PAGE;

	ecc_sw_hamming_calculate(buffer, SM_SMALL_PAGE, ecc, sm_order);
	if (ecc_sw_hamming_correct(buffer, ecc, oob->ecc2, SM_SMALL_PAGE,
				   sm_order) < 0)
		return -EIO;
	return 0;
}

/* Reads a sector + oob*/
static int sm_read_sector(struct sm_ftl *ftl,
			  int zone, int block, int boffset,
			  uint8_t *buffer, struct sm_oob *oob)
{
	struct mtd_info *mtd = ftl->trans->mtd;
	struct mtd_oob_ops ops;
	struct sm_oob tmp_oob;
	int ret = -EIO;
	int try = 0;

	/* FTL can contain -1 entries that are by default filled with bits */
	if (block == -1) {
		if (buffer)
			memset(buffer, 0xFF, SM_SECTOR_SIZE);
		return 0;
	}

	/* User might not need the oob, but we do for data verification */
	if (!oob)
		oob = &tmp_oob;

	ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
	ops.ooboffs = 0;
	ops.ooblen = SM_OOB_SIZE;
	ops.oobbuf = (void *)oob;
	ops.len = SM_SECTOR_SIZE;
	ops.datbuf = buffer;

again:
	if (try++) {
		/* Avoid infinite recursion on CIS reads, sm_recheck_media
			won't help anyway */
		if (zone == 0 && block == ftl->cis_block && boffset ==
			ftl->cis_boffset)
			return ret;

		/* Test if media is stable */
		if (try == 3 || sm_recheck_media(ftl))
			return ret;
	}

	/* Unfortunately, oob read will _always_ succeed,
		despite card removal..... */
	ret = mtd_read_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);

	/* Test for unknown errors */
	if (ret != 0 && !mtd_is_bitflip_or_eccerr(ret)) {
		dbg("read of block %d at zone %d, failed due to error (%d)",
			block, zone, ret);
		goto again;
	}

	/* Do a basic test on the oob, to guard against returned garbage */
	if (oob->reserved != 0xFFFFFFFF && !is_power_of_2(~oob->reserved))
		goto again;

	/* This should never happen, unless there is a bug in the mtd driver */
	WARN_ON(ops.oobretlen != SM_OOB_SIZE);
	WARN_ON(buffer && ops.retlen != SM_SECTOR_SIZE);

	if (!buffer)
		return 0;

	/* Test if sector marked as bad */
	if (!sm_sector_valid(oob)) {
		dbg("read of block %d at zone %d, failed because it is marked"
			" as bad" , block, zone);
		goto again;
	}

	/* Test ECC*/
	if (mtd_is_eccerr(ret) ||
		(ftl->smallpagenand && sm_correct_sector(buffer, oob))) {

		dbg("read of block %d at zone %d, failed due to ECC error",
			block, zone);
		goto again;
	}

	return 0;
}

/* Writes a sector to media */
static int sm_write_sector(struct sm_ftl *ftl,
			   int zone, int block, int boffset,
			   uint8_t *buffer, struct sm_oob *oob)
{
	struct mtd_oob_ops ops;
	struct mtd_info *mtd = ftl->trans->mtd;
	int ret;

	BUG_ON(ftl->readonly);

	if (zone == 0 && (block == ftl->cis_block || block == 0)) {
		dbg("attempted to write the CIS!");
		return -EIO;
	}

	if (ftl->unstable)
		return -EIO;

	ops.mode = ftl->smallpagenand ? MTD_OPS_RAW : MTD_OPS_PLACE_OOB;
	ops.len = SM_SECTOR_SIZE;
	ops.datbuf = buffer;
	ops.ooboffs = 0;
	ops.ooblen = SM_OOB_SIZE;
	ops.oobbuf = (void *)oob;

	ret = mtd_write_oob(mtd, sm_mkoffset(ftl, zone, block, boffset), &ops);

	/* Now we assume that hardware will catch write bitflip errors */

	if (ret) {
		dbg("write to block %d at zone %d, failed with error %d",
			block, zone, ret);

		sm_recheck_media(ftl);
		return ret;
	}

	/* This should never happen, unless there is a bug in the driver */
	WARN_ON(ops.oobretlen != SM_OOB_SIZE);
	WARN_ON(buffer && ops.retlen != SM_SECTOR_SIZE);

	return 0;
}

/* ------------------------ block IO ------------------------------------- */

/* Write a block using data and lba, and invalid sector bitmap */
static int sm_write_block(struct sm_ftl *ftl, uint8_t *buf,
			  int zone, int block, int lba,
			  unsigned long invalid_bitmap)
{
	bool sm_order = IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC);
	struct sm_oob oob;
	int boffset;
	int retry = 0;

	/* Initialize the oob with requested values */
	memset(&oob, 0xFF, SM_OOB_SIZE);
	sm_write_lba(&oob, lba);
restart:
	if (ftl->unstable)
		return -EIO;

	for (boffset = 0; boffset < ftl->block_size;
				boffset += SM_SECTOR_SIZE) {

		oob.data_status = 0xFF;

		if (test_bit(boffset / SM_SECTOR_SIZE, &invalid_bitmap)) {

			sm_printk("sector %d of block at LBA %d of zone %d"
				" couldn't be read, marking it as invalid",
				boffset / SM_SECTOR_SIZE, lba, zone);

			oob.data_status = 0;
		}

		if (ftl->smallpagenand) {
			ecc_sw_hamming_calculate(buf + boffset,
						 SM_SMALL_PAGE, oob.ecc1,
						 sm_order);

			ecc_sw_hamming_calculate(buf + boffset + SM_SMALL_PAGE,
						 SM_SMALL_PAGE, oob.ecc2,
						 sm_order);
		}
		if (!sm_write_sector(ftl, zone, block, boffset,
							buf + boffset, &oob))
			continue;

		if (!retry) {

			/* If write fails. try to erase the block */
			/* This is safe, because we never write in blocks
				that contain valuable data.
			This is intended to repair block that are marked
			as erased, but that isn't fully erased*/

			if (sm_erase_block(ftl, zone, block, 0))
				return -EIO;

			retry = 1;
			goto restart;
		} else {
			sm_mark_block_bad(ftl, zone, block);
			return -EIO;
		}
	}
	return 0;
}


/* Mark whole block at offset 'offs' as bad. */
static void sm_mark_block_bad(struct sm_ftl *ftl, int zone, int block)
{
	struct sm_oob oob;
	int boffset;

	memset(&oob, 0xFF, SM_OOB_SIZE);
	oob.block_status = 0xF0;

	if (ftl->unstable)
		return;

	if (sm_recheck_media(ftl))
		return;

	sm_printk("marking block %d of zone %d as bad", block, zone);

	/* We aren't checking the return value, because we don't care */
	/* This also fails on fake xD cards, but I guess these won't expose
		any bad blocks till fail completely */
	for (boffset = 0; boffset < ftl->block_size; boffset += SM_SECTOR_SIZE)
		sm_write_sector(ftl, zone, block, boffset, NULL, &oob);
}

/*
 * Erase a block within a zone
 * If erase succeeds, it updates free block fifo, otherwise marks block as bad
 */
static int sm_erase_block(struct sm_ftl *ftl, int zone_num, uint16_t block,
			  int put_free)
{
	struct ftl_zone *zone = &ftl->zones[zone_num];
	struct mtd_info *mtd = ftl->trans->mtd;
	struct erase_info erase;

	erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
	erase.len = ftl->block_size;

	if (ftl->unstable)
		return -EIO;

	BUG_ON(ftl->readonly);

	if (zone_num == 0 && (block == ftl->cis_block || block == 0)) {
		sm_printk("attempted to erase the CIS!");
		return -EIO;
	}

	if (mtd_erase(mtd, &erase)) {
		sm_printk("erase of block %d in zone %d failed",
							block, zone_num);
		goto error;
	}

	if (put_free)
		kfifo_in(&zone->free_sectors,
			(const unsigned char *)&block, sizeof(block));

	return 0;
error:
	sm_mark_block_bad(ftl, zone_num, block);
	return -EIO;
}

/* Thoroughly test that block is valid. */
static int sm_check_block(struct sm_ftl *ftl, int zone, int block)
{
	int boffset;
	struct sm_oob oob;
	int lbas[] = { -3, 0, 0, 0 };
	int i = 0;
	int test_lba;


	/* First just check that block doesn't look fishy */
	/* Only blocks that are valid or are sliced in two parts, are
		accepted */
	for (boffset = 0; boffset < ftl->block_size;
					boffset += SM_SECTOR_SIZE) {

		/* This shouldn't happen anyway */
		if (sm_read_sector(ftl, zone, block, boffset, NULL, &oob))
			return -2;

		test_lba = sm_read_lba(&oob);

		if (lbas[i] != test_lba)
			lbas[++i] = test_lba;

		/* If we found three different LBAs, something is fishy */
		if (i == 3)
			return -EIO;
	}

	/* If the block is sliced (partially erased usually) erase it */
	if (i == 2) {
		sm_erase_block(ftl, zone, block, 1);
		return 1;
	}

	return 0;
}

/* ----------------- media scanning --------------------------------- */
static const struct chs_entry chs_table[] = {
	{ 1,    125,  4,  4  },
	{ 2,    125,  4,  8  },
	{ 4,    250,  4,  8  },
	{ 8,    250,  4,  16 },
	{ 16,   500,  4,  16 },
	{ 32,   500,  8,  16 },
	{ 64,   500,  8,  32 },
	{ 128,  500,  16, 32 },
	{ 256,  1000, 16, 32 },
	{ 512,  1015, 32, 63 },
	{ 1024, 985,  33, 63 },
	{ 2048, 985,  33, 63 },
	{ 0 },
};


static const uint8_t cis_signature[] = {
	0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, 0xDF, 0x01, 0x20
};
/* Find out media parameters.
 * This ideally has to be based on nand id, but for now device size is enough */
static int sm_get_media_info(struct sm_ftl *ftl, struct mtd_info *mtd)
{
	int i;
	int size_in_megs = mtd->size / (1024 * 1024);

	ftl->readonly = mtd->type == MTD_ROM;

	/* Manual settings for very old devices */
	ftl->zone_count = 1;
	ftl->smallpagenand = 0;

	switch (size_in_megs) {
	case 1:
		/* 1 MiB flash/rom SmartMedia card (256 byte pages)*/
		ftl->zone_size = 256;
		ftl->max_lba = 250;
		ftl->block_size = 8 * SM_SECTOR_SIZE;
		ftl->smallpagenand = 1;

		break;
	case 2:
		/* 2 MiB flash SmartMedia (256 byte pages)*/
		if (mtd->writesize == SM_SMALL_PAGE) {
			ftl->zone_size = 512;
			ftl->max_lba = 500;
			ftl->block_size = 8 * SM_SECTOR_SIZE;
			ftl->smallpagenand = 1;
		/* 2 MiB rom SmartMedia */
		} else {

			if (!ftl->readonly)
				return -ENODEV;

			ftl->zone_size = 256;
			ftl->max_lba = 250;
			ftl->block_size = 16 * SM_SECTOR_SIZE;
		}
		break;
	case 4:
		/* 4 MiB flash/rom SmartMedia device */
		ftl->zone_size = 512;
		ftl->max_lba = 500;
		ftl->block_size = 16 * SM_SECTOR_SIZE;
		break;
	case 8:
		/* 8 MiB flash/rom SmartMedia device */
		ftl->zone_size = 1024;
		ftl->max_lba = 1000;
		ftl->block_size = 16 * SM_SECTOR_SIZE;
	}

	/* Minimum xD size is 16MiB. Also, all xD cards have standard zone
	   sizes. SmartMedia cards exist up to 128 MiB and have same layout*/
	if (size_in_megs >= 16) {
		ftl->zone_count = size_in_megs / 16;
		ftl->zone_size = 1024;
		ftl->max_lba = 1000;
		ftl->block_size = 32 * SM_SECTOR_SIZE;
	}

	/* Test for proper write,erase and oob sizes */
	if (mtd->erasesize > ftl->block_size)
		return -ENODEV;

	if (mtd->writesize > SM_SECTOR_SIZE)
		return -ENODEV;

	if (ftl->smallpagenand && mtd->oobsize < SM_SMALL_OOB_SIZE)
		return -ENODEV;

	if (!ftl->smallpagenand && mtd->oobsize < SM_OOB_SIZE)
		return -ENODEV;

	/* We use OOB */
	if (!mtd_has_oob(mtd))
		return -ENODEV;

	/* Find geometry information */
	for (i = 0 ; i < ARRAY_SIZE(chs_table) ; i++) {
		if (chs_table[i].size == size_in_megs) {
			ftl->cylinders = chs_table[i].cyl;
			ftl->heads = chs_table[i].head;
			ftl->sectors = chs_table[i].sec;
			return 0;
		}
	}

	sm_printk("media has unknown size : %dMiB", size_in_megs);
	ftl->cylinders = 985;
	ftl->heads =  33;
	ftl->sectors = 63;
	return 0;
}

/* Validate the CIS */
static int sm_read_cis(struct sm_ftl *ftl)
{
	struct sm_oob oob;

	if (sm_read_sector(ftl,
		0, ftl->cis_block, ftl->cis_boffset, ftl->cis_buffer, &oob))
			return -EIO;

	if (!sm_sector_valid(&oob) || !sm_block_valid(&oob))
		return -EIO;

	if (!memcmp(ftl->cis_buffer + ftl->cis_page_offset,
			cis_signature, sizeof(cis_signature))) {
		return 0;
	}

	return -EIO;
}

/* Scan the media for the CIS */
static int sm_find_cis(struct sm_ftl *ftl)
{
	struct sm_oob oob;
	int block, boffset;
	int block_found = 0;
	int cis_found = 0;

	/* Search for first valid block */
	for (block = 0 ; block < ftl->zone_size - ftl->max_lba ; block++) {

		if (sm_read_sector(ftl, 0, block, 0, NULL, &oob))
			continue;

		if (!sm_block_valid(&oob))
			continue;
		block_found = 1;
		break;
	}

	if (!block_found)
		return -EIO;

	/* Search for first valid sector in this block */
	for (boffset = 0 ; boffset < ftl->block_size;
						boffset += SM_SECTOR_SIZE) {

		if (sm_read_sector(ftl, 0, block, boffset, NULL, &oob))
			continue;

		if (!sm_sector_valid(&oob))
			continue;
		break;
	}

	if (boffset == ftl->block_size)
		return -EIO;

	ftl->cis_block = block;
	ftl->cis_boffset = boffset;
	ftl->cis_page_offset = 0;

	cis_found = !sm_read_cis(ftl);

	if (!cis_found) {
		ftl->cis_page_offset = SM_SMALL_PAGE;
		cis_found = !sm_read_cis(ftl);
	}

	if (cis_found) {
		dbg("CIS block found at offset %x",
			block * ftl->block_size +
				boffset + ftl->cis_page_offset);
		return 0;
	}
	return -EIO;
}

/* Basic test to determine if underlying mtd device if functional */
static int sm_recheck_media(struct sm_ftl *ftl)
{
	if (sm_read_cis(ftl)) {

		if (!ftl->unstable) {
			sm_printk("media unstable, not allowing writes");
			ftl->unstable = 1;
		}
		return -EIO;
	}
	return 0;
}

/* Initialize a FTL zone */
static int sm_init_zone(struct sm_ftl *ftl, int zone_num)
{
	struct ftl_zone *zone = &ftl->zones[zone_num];
	struct sm_oob oob;
	uint16_t block;
	int lba;
	int i = 0;
	int len;

	dbg("initializing zone %d", zone_num);

	/* Allocate memory for FTL table */
	zone->lba_to_phys_table = kmalloc_array(ftl->max_lba, 2, GFP_KERNEL);

	if (!zone->lba_to_phys_table)
		return -ENOMEM;
	memset(zone->lba_to_phys_table, -1, ftl->max_lba * 2);


	/* Allocate memory for free sectors FIFO */
	if (kfifo_alloc(&zone->free_sectors, ftl->zone_size * 2, GFP_KERNEL)) {
		kfree(zone->lba_to_phys_table);
		return -ENOMEM;
	}

	/* Now scan the zone */
	for (block = 0 ; block < ftl->zone_size ; block++) {

		/* Skip blocks till the CIS (including) */
		if (zone_num == 0 && block <= ftl->cis_block)
			continue;

		/* Read the oob of first sector */
		if (sm_read_sector(ftl, zone_num, block, 0, NULL, &oob)) {
			kfifo_free(&zone->free_sectors);
			kfree(zone->lba_to_phys_table);
			return -EIO;
		}

		/* Test to see if block is erased. It is enough to test
			first sector, because erase happens in one shot */
		if (sm_block_erased(&oob)) {
			kfifo_in(&zone->free_sectors,
				(unsigned char *)&block, 2);
			continue;
		}

		/* If block is marked as bad, skip it */
		/* This assumes we can trust first sector*/
		/* However the way the block valid status is defined, ensures
			very low probability of failure here */
		if (!sm_block_valid(&oob)) {
			dbg("PH %04d <-> <marked bad>", block);
			continue;
		}


		lba = sm_read_lba(&oob);

		/* Invalid LBA means that block is damaged. */
		/* We can try to erase it, or mark it as bad, but
			lets leave that to recovery application */
		if (lba == -2 || lba >= ftl->max_lba) {
			dbg("PH %04d <-> LBA %04d(bad)", block, lba);
			continue;
		}


		/* If there is no collision,
			just put the sector in the FTL table */
		if (zone->lba_to_phys_table[lba] < 0) {
			dbg_verbose("PH %04d <-> LBA %04d", block, lba);
			zone->lba_to_phys_table[lba] = block;
			continue;
		}

		sm_printk("collision"
			" of LBA %d between blocks %d and %d in zone %d",
			lba, zone->lba_to_phys_table[lba], block, zone_num);

		/* Test that this block is valid*/
		if (sm_check_block(ftl, zone_num, block))
			continue;

		/* Test now the old block */
		if (sm_check_block(ftl, zone_num,
					zone->lba_to_phys_table[lba])) {
			zone->lba_to_phys_table[lba] = block;
			continue;
		}

		/* If both blocks are valid and share same LBA, it means that
			they hold different versions of same data. It not
			known which is more recent, thus just erase one of them
		*/
		sm_printk("both blocks are valid, erasing the later");
		sm_erase_block(ftl, zone_num, block, 1);
	}

	dbg("zone initialized");
	zone->initialized = 1;

	/* No free sectors, means that the zone is heavily damaged, write won't
		work, but it can still can be (partially) read */
	if (!kfifo_len(&zone->free_sectors)) {
		sm_printk("no free blocks in zone %d", zone_num);
		return 0;
	}

	/* Randomize first block we write to */
	get_random_bytes(&i, 2);
	i %= (kfifo_len(&zone->free_sectors) / 2);

	while (i--) {
		len = kfifo_out(&zone->free_sectors,
					(unsigned char *)&block, 2);
		WARN_ON(len != 2);
		kfifo_in(&zone->free_sectors, (const unsigned char *)&block, 2);
	}
	return 0;
}

/* Get and automatically initialize an FTL mapping for one zone */
static struct ftl_zone *sm_get_zone(struct sm_ftl *ftl, int zone_num)
{
	struct ftl_zone *zone;
	int error;

	BUG_ON(zone_num >= ftl->zone_count);
	zone = &ftl->zones[zone_num];

	if (!zone->initialized) {
		error = sm_init_zone(ftl, zone_num);

		if (error)
			return ERR_PTR(error);
	}
	return zone;
}


/* ----------------- cache handling ------------------------------------------*/

/* Initialize the one block cache */
static void sm_cache_init(struct sm_ftl *ftl)
{
	ftl->cache_data_invalid_bitmap = 0xFFFFFFFF;
	ftl->cache_clean = 1;
	ftl->cache_zone = -1;
	ftl->cache_block = -1;
	/*memset(ftl->cache_data, 0xAA, ftl->block_size);*/
}

/* Put sector in one block cache */
static void sm_cache_put(struct sm_ftl *ftl, char *buffer, int boffset)
{
	memcpy(ftl->cache_data + boffset, buffer, SM_SECTOR_SIZE);
	clear_bit(boffset / SM_SECTOR_SIZE, &ftl->cache_data_invalid_bitmap);
	ftl->cache_clean = 0;
}

/* Read a sector from the cache */
static int sm_cache_get(struct sm_ftl *ftl, char *buffer, int boffset)
{
	if (test_bit(boffset / SM_SECTOR_SIZE,
		&ftl->cache_data_invalid_bitmap))
			return -1;

	memcpy(buffer, ftl->cache_data + boffset, SM_SECTOR_SIZE);
	return 0;
}

/* Write the cache to hardware */
static int sm_cache_flush(struct sm_ftl *ftl)
{
	struct ftl_zone *zone;

	int sector_num;
	uint16_t write_sector;
	int zone_num = ftl->cache_zone;
	int block_num;

	if (ftl->cache_clean)
		return 0;

	if (ftl->unstable)
		return -EIO;

	BUG_ON(zone_num < 0);
	zone = &ftl->zones[zone_num];
	block_num = zone->lba_to_phys_table[ftl->cache_block];


	/* Try to read all unread areas of the cache block*/
	for_each_set_bit(sector_num, &ftl->cache_data_invalid_bitmap,
		ftl->block_size / SM_SECTOR_SIZE) {

		if (!sm_read_sector(ftl,
			zone_num, block_num, sector_num * SM_SECTOR_SIZE,
			ftl->cache_data + sector_num * SM_SECTOR_SIZE, NULL))
				clear_bit(sector_num,
					&ftl->cache_data_invalid_bitmap);
	}
restart:

	if (ftl->unstable)
		return -EIO;

	/* If there are no spare blocks, */
	/* we could still continue by erasing/writing the current block,
		but for such worn out media it doesn't worth the trouble,
			and the dangers */
	if (kfifo_out(&zone->free_sectors,
				(unsigned char *)&write_sector, 2) != 2) {
		dbg("no free sectors for write!");
		return -EIO;
	}


	if (sm_write_block(ftl, ftl->cache_data, zone_num, write_sector,
		ftl->cache_block, ftl->cache_data_invalid_bitmap))
			goto restart;

	/* Update the FTL table */
	zone->lba_to_phys_table[ftl->cache_block] = write_sector;

	/* Write succesfull, so erase and free the old block */
	if (block_num > 0)
		sm_erase_block(ftl, zone_num, block_num, 1);

	sm_cache_init(ftl);
	return 0;
}


/* flush timer, runs a second after last write */
static void sm_cache_flush_timer(struct timer_list *t)
{
	struct sm_ftl *ftl = from_timer(ftl, t, timer);
	queue_work(cache_flush_workqueue, &ftl->flush_work);
}

/* cache flush work, kicked by timer */
static void sm_cache_flush_work(struct work_struct *work)
{
	struct sm_ftl *ftl = container_of(work, struct sm_ftl, flush_work);
	mutex_lock(&ftl->mutex);
	sm_cache_flush(ftl);
	mutex_unlock(&ftl->mutex);
	return;
}

/* ---------------- outside interface -------------------------------------- */

/* outside interface: read a sector */
static int sm_read(struct mtd_blktrans_dev *dev,
		   unsigned long sect_no, char *buf)
{
	struct sm_ftl *ftl = dev->priv;
	struct ftl_zone *zone;
	int error = 0, in_cache = 0;
	int zone_num, block, boffset;

	sm_break_offset(ftl, sect_no << 9, &zone_num, &block, &boffset);
	mutex_lock(&ftl->mutex);


	zone = sm_get_zone(ftl, zone_num);
	if (IS_ERR(zone)) {
		error = PTR_ERR(zone);
		goto unlock;
	}

	/* Have to look at cache first */
	if (ftl->cache_zone == zone_num && ftl->cache_block == block) {
		in_cache = 1;
		if (!sm_cache_get(ftl, buf, boffset))
			goto unlock;
	}

	/* Translate the block and return if doesn't exist in the table */
	block = zone->lba_to_phys_table[block];

	if (block == -1) {
		memset(buf, 0xFF, SM_SECTOR_SIZE);
		goto unlock;
	}

	if (sm_read_sector(ftl, zone_num, block, boffset, buf, NULL)) {
		error = -EIO;
		goto unlock;
	}

	if (in_cache)
		sm_cache_put(ftl, buf, boffset);
unlock:
	mutex_unlock(&ftl->mutex);
	return error;
}

/* outside interface: write a sector */
static int sm_write(struct mtd_blktrans_dev *dev,
				unsigned long sec_no, char *buf)
{
	struct sm_ftl *ftl = dev->priv;
	struct ftl_zone *zone;
	int error = 0, zone_num, block, boffset;

	BUG_ON(ftl->readonly);
	sm_break_offset(ftl, sec_no << 9, &zone_num, &block, &boffset);

	/* No need in flush thread running now */
	del_timer(&ftl->timer);
	mutex_lock(&ftl->mutex);

	zone = sm_get_zone(ftl, zone_num);
	if (IS_ERR(zone)) {
		error = PTR_ERR(zone);
		goto unlock;
	}

	/* If entry is not in cache, flush it */
	if (ftl->cache_block != block || ftl->cache_zone != zone_num) {

		error = sm_cache_flush(ftl);
		if (error)
			goto unlock;

		ftl->cache_block = block;
		ftl->cache_zone = zone_num;
	}

	sm_cache_put(ftl, buf, boffset);
unlock:
	mod_timer(&ftl->timer, jiffies + msecs_to_jiffies(cache_timeout));
	mutex_unlock(&ftl->mutex);
	return error;
}

/* outside interface: flush everything */
static int sm_flush(struct mtd_blktrans_dev *dev)
{
	struct sm_ftl *ftl = dev->priv;
	int retval;

	mutex_lock(&ftl->mutex);
	retval =  sm_cache_flush(ftl);
	mutex_unlock(&ftl->mutex);
	return retval;
}

/* outside interface: device is released */
static void sm_release(struct mtd_blktrans_dev *dev)
{
	struct sm_ftl *ftl = dev->priv;

	mutex_lock(&ftl->mutex);
	del_timer_sync(&ftl->timer);
	cancel_work_sync(&ftl->flush_work);
	sm_cache_flush(ftl);
	mutex_unlock(&ftl->mutex);
}

/* outside interface: get geometry */
static int sm_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
{
	struct sm_ftl *ftl = dev->priv;
	geo->heads = ftl->heads;
	geo->sectors = ftl->sectors;
	geo->cylinders = ftl->cylinders;
	return 0;
}

/* external interface: main initialization function */
static void sm_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
{
	struct mtd_blktrans_dev *trans;
	struct sm_ftl *ftl;

	/* Allocate & initialize our private structure */
	ftl = kzalloc(sizeof(struct sm_ftl), GFP_KERNEL);
	if (!ftl)
		goto error1;


	mutex_init(&ftl->mutex);
	timer_setup(&ftl->timer, sm_cache_flush_timer, 0);
	INIT_WORK(&ftl->flush_work, sm_cache_flush_work);

	/* Read media information */
	if (sm_get_media_info(ftl, mtd)) {
		dbg("found unsupported mtd device, aborting");
		goto error2;
	}


	/* Allocate temporary CIS buffer for read retry support */
	ftl->cis_buffer = kzalloc(SM_SECTOR_SIZE, GFP_KERNEL);
	if (!ftl->cis_buffer)
		goto error2;

	/* Allocate zone array, it will be initialized on demand */
	ftl->zones = kcalloc(ftl->zone_count, sizeof(struct ftl_zone),
								GFP_KERNEL);
	if (!ftl->zones)
		goto error3;

	/* Allocate the cache*/
	ftl->cache_data = kzalloc(ftl->block_size, GFP_KERNEL);

	if (!ftl->cache_data)
		goto error4;

	sm_cache_init(ftl);


	/* Allocate upper layer structure and initialize it */
	trans = kzalloc(sizeof(struct mtd_blktrans_dev), GFP_KERNEL);
	if (!trans)
		goto error5;

	ftl->trans = trans;
	trans->priv = ftl;

	trans->tr = tr;
	trans->mtd = mtd;
	trans->devnum = -1;
	trans->size = (ftl->block_size * ftl->max_lba * ftl->zone_count) >> 9;
	trans->readonly = ftl->readonly;

	if (sm_find_cis(ftl)) {
		dbg("CIS not found on mtd device, aborting");
		goto error6;
	}

	ftl->disk_attributes = sm_create_sysfs_attributes(ftl);
	if (!ftl->disk_attributes)
		goto error6;
	trans->disk_attributes = ftl->disk_attributes;

	sm_printk("Found %d MiB xD/SmartMedia FTL on mtd%d",
		(int)(mtd->size / (1024 * 1024)), mtd->index);

	dbg("FTL layout:");
	dbg("%d zone(s), each consists of %d blocks (+%d spares)",
		ftl->zone_count, ftl->max_lba,
		ftl->zone_size - ftl->max_lba);
	dbg("each block consists of %d bytes",
		ftl->block_size);


	/* Register device*/
	if (add_mtd_blktrans_dev(trans)) {
		dbg("error in mtdblktrans layer");
		goto error6;
	}
	return;
error6:
	kfree(trans);
error5:
	kfree(ftl->cache_data);
error4:
	kfree(ftl->zones);
error3:
	kfree(ftl->cis_buffer);
error2:
	kfree(ftl);
error1:
	return;
}

/* main interface: device {surprise,} removal */
static void sm_remove_dev(struct mtd_blktrans_dev *dev)
{
	struct sm_ftl *ftl = dev->priv;
	int i;

	del_mtd_blktrans_dev(dev);
	ftl->trans = NULL;

	for (i = 0 ; i < ftl->zone_count; i++) {

		if (!ftl->zones[i].initialized)
			continue;

		kfree(ftl->zones[i].lba_to_phys_table);
		kfifo_free(&ftl->zones[i].free_sectors);
	}

	sm_delete_sysfs_attributes(ftl);
	kfree(ftl->cis_buffer);
	kfree(ftl->zones);
	kfree(ftl->cache_data);
	kfree(ftl);
}

static struct mtd_blktrans_ops sm_ftl_ops = {
	.name		= "smblk",
	.major		= 0,
	.part_bits	= SM_FTL_PARTN_BITS,
	.blksize	= SM_SECTOR_SIZE,
	.getgeo		= sm_getgeo,

	.add_mtd	= sm_add_mtd,
	.remove_dev	= sm_remove_dev,

	.readsect	= sm_read,
	.writesect	= sm_write,

	.flush		= sm_flush,
	.release	= sm_release,

	.owner		= THIS_MODULE,
};

static __init int sm_module_init(void)
{
	int error = 0;

	cache_flush_workqueue = create_freezable_workqueue("smflush");
	if (!cache_flush_workqueue)
		return -ENOMEM;

	error = register_mtd_blktrans(&sm_ftl_ops);
	if (error)
		destroy_workqueue(cache_flush_workqueue);
	return error;

}

static void __exit sm_module_exit(void)
{
	destroy_workqueue(cache_flush_workqueue);
	deregister_mtd_blktrans(&sm_ftl_ops);
}

module_init(sm_module_init);
module_exit(sm_module_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Maxim Levitsky <maximlevitsky@gmail.com>");
MODULE_DESCRIPTION("Smartmedia/xD mtd translation layer");
