diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
new file mode 100644
index 0000000..c23184a
--- /dev/null
+++ b/drivers/mtd/sm_ftl.c
@@ -0,0 +1,1297 @@
+/*
+ * Copyright © 2009 - Maxim Levitsky
+ * SmartMedia/xD translation layer
+ *
+ * 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 <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.h>
+#include "nand/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 = kzalloc(sizeof(struct attribute *) * (NUM_ATTRIBUTES + 1),
+								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 offset,
+			    int *zone, int *block, int *boffset)
+{
+	*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)
+{
+	uint8_t ecc[3];
+
+	__nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc);
+	if (__nand_correct_data(buffer, ecc, oob->ecc1, SM_SMALL_PAGE) < 0)
+		return -EIO;
+
+	buffer += SM_SMALL_PAGE;
+
+	__nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc);
+	if (__nand_correct_data(buffer, ecc, oob->ecc2, SM_SMALL_PAGE) < 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) {
+		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)
+{
+	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"
+				" coudn't be read, marking it as invalid",
+				boffset / SM_SECTOR_SIZE, lba, zone);
+
+			oob.data_status = 0;
+		}
+
+		if (ftl->smallpagenand) {
+			__nand_calculate_ecc(buf + boffset,
+						SM_SMALL_PAGE, oob.ecc1);
+
+			__nand_calculate_ecc(buf + boffset + SM_SMALL_PAGE,
+						SM_SMALL_PAGE, oob.ecc2);
+		}
+		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.mtd = mtd;
+	erase.callback = sm_erase_callback;
+	erase.addr = sm_mkoffset(ftl, zone_num, block, 0);
+	erase.len = ftl->block_size;
+	erase.priv = (u_long)ftl;
+
+	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 (erase.state == MTD_ERASE_PENDING)
+		wait_for_completion(&ftl->erase_completion);
+
+	if (erase.state != MTD_ERASE_DONE) {
+		sm_printk("erase of block %d in zone %d failed after wait",
+			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;
+}
+
+static void sm_erase_callback(struct erase_info *self)
+{
+	struct sm_ftl *ftl = (struct sm_ftl *)self->priv;
+	complete(&ftl->erase_completion);
+}
+
+/* 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(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))
+			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(unsigned long data)
+{
+	struct sm_ftl *ftl = (struct sm_ftl *)data;
+	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);
+	setup_timer(&ftl->timer, sm_cache_flush_timer, (unsigned long)ftl);
+	INIT_WORK(&ftl->flush_work, sm_cache_flush_work);
+	init_completion(&ftl->erase_completion);
+
+	/* 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 = kzalloc(sizeof(struct ftl_zone) * ftl->zone_count,
+								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");
