/*
 * NAND Flash Controller Device Driver
 * Copyright (c) 2009, Intel Corporation and its suppliers.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.,
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "ffsport.h"
#include "flash.h"
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/blkdev.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/kthread.h>
#include <linux/log2.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/async.h>

/**** Helper functions used for Div, Remainder operation on u64 ****/

/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     GLOB_Calc_Used_Bits
* Inputs:       Power of 2 number
* Outputs:      Number of Used Bits
*               0, if the argument is 0
* Description:  Calculate the number of bits used by a given power of 2 number
*               Number can be up to 32 bit
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
int GLOB_Calc_Used_Bits(u32 n)
{
	int tot_bits = 0;

	if (n >= 1 << 16) {
		n >>= 16;
		tot_bits += 16;
	}

	if (n >= 1 << 8) {
		n >>=  8;
		tot_bits +=  8;
	}

	if (n >= 1 << 4) {
		n >>=  4;
		tot_bits +=  4;
	}

	if (n >= 1 << 2) {
		n >>=  2;
		tot_bits +=  2;
	}

	if (n >= 1 << 1)
		tot_bits +=  1;

	return ((n == 0) ? (0) : tot_bits);
}

/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     GLOB_u64_Div
* Inputs:       Number of u64
*               A power of 2 number as Division
* Outputs:      Quotient of the Divisor operation
* Description:  It divides the address by divisor by using bit shift operation
*               (essentially without explicitely using "/").
*               Divisor is a power of 2 number and Divided is of u64
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
u64 GLOB_u64_Div(u64 addr, u32 divisor)
{
	return  (u64)(addr >> GLOB_Calc_Used_Bits(divisor));
}

/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
* Function:     GLOB_u64_Remainder
* Inputs:       Number of u64
*               Divisor Type (1 -PageAddress, 2- BlockAddress)
* Outputs:      Remainder of the Division operation
* Description:  It calculates the remainder of a number (of u64) by
*               divisor(power of 2 number ) by using bit shifting and multiply
*               operation(essentially without explicitely using "/").
*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type)
{
	u64 result = 0;

	if (divisor_type == 1) { /* Remainder -- Page */
		result = (addr >> DeviceInfo.nBitsInPageDataSize);
		result = result * DeviceInfo.wPageDataSize;
	} else if (divisor_type == 2) { /* Remainder -- Block */
		result = (addr >> DeviceInfo.nBitsInBlockDataSize);
		result = result * DeviceInfo.wBlockDataSize;
	}

	result = addr - result;

	return result;
}

#define NUM_DEVICES             1
#define PARTITIONS              8

#define GLOB_SBD_NAME          "nd"
#define GLOB_SBD_IRQ_NUM       (29)

#define GLOB_SBD_IOCTL_GC                        (0x7701)
#define GLOB_SBD_IOCTL_WL                        (0x7702)
#define GLOB_SBD_IOCTL_FORMAT                    (0x7703)
#define GLOB_SBD_IOCTL_ERASE_FLASH               (0x7704)
#define GLOB_SBD_IOCTL_FLUSH_CACHE               (0x7705)
#define GLOB_SBD_IOCTL_COPY_BLK_TABLE            (0x7706)
#define GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE  (0x7707)
#define GLOB_SBD_IOCTL_GET_NAND_INFO             (0x7708)
#define GLOB_SBD_IOCTL_WRITE_DATA                (0x7709)
#define GLOB_SBD_IOCTL_READ_DATA                 (0x770A)

static int reserved_mb = 0;
module_param(reserved_mb, int, 0);
MODULE_PARM_DESC(reserved_mb, "Reserved space for OS image, in MiB (default 25 MiB)");

int nand_debug_level;
module_param(nand_debug_level, int, 0644);
MODULE_PARM_DESC(nand_debug_level, "debug level value: 1-3");

MODULE_LICENSE("GPL");

struct spectra_nand_dev {
	struct pci_dev *dev;
	u64 size;
	u16 users;
	spinlock_t qlock;
	void __iomem *ioaddr;  /* Mapped address */
	struct request_queue *queue;
	struct task_struct *thread;
	struct gendisk *gd;
	u8 *tmp_buf;
};


static int GLOB_SBD_majornum;

static char *GLOB_version = GLOB_VERSION;

static struct spectra_nand_dev nand_device[NUM_DEVICES];

static struct mutex spectra_lock;

static int res_blks_os = 1;

struct spectra_indentfy_dev_tag IdentifyDeviceData;

static int force_flush_cache(void)
{
	nand_dbg_print(NAND_DBG_DEBUG, "%s, Line %d, Function: %s\n",
		__FILE__, __LINE__, __func__);

	if (ERR == GLOB_FTL_Flush_Cache()) {
		printk(KERN_ERR "Fail to Flush FTL Cache!\n");
		return -EFAULT;
	}
#if CMD_DMA
		if (glob_ftl_execute_cmds())
			return -EIO;
		else
			return 0;
#endif
	return 0;
}

struct ioctl_rw_page_info {
	u8 *data;
	unsigned int page;
};

static int ioctl_read_page_data(unsigned long arg)
{
	u8 *buf;
	struct ioctl_rw_page_info info;
	int result = PASS;

	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
		return -EFAULT;

	buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
	if (!buf) {
		printk(KERN_ERR "ioctl_read_page_data: "
		       "failed to allocate memory\n");
		return -ENOMEM;
	}

	mutex_lock(&spectra_lock);
	result = GLOB_FTL_Page_Read(buf,
		(u64)info.page * IdentifyDeviceData.PageDataSize);
	mutex_unlock(&spectra_lock);

	if (copy_to_user((void __user *)info.data, buf,
			   IdentifyDeviceData.PageDataSize)) {
		printk(KERN_ERR "ioctl_read_page_data: "
		       "failed to copy user data\n");
		kfree(buf);
		return -EFAULT;
	}

	kfree(buf);
	return result;
}

static int ioctl_write_page_data(unsigned long arg)
{
	u8 *buf;
	struct ioctl_rw_page_info info;
	int result = PASS;

	if (copy_from_user(&info, (void __user *)arg, sizeof(info)))
		return -EFAULT;

	buf = memdup_user((void __user *)info.data,
			  IdentifyDeviceData.PageDataSize);
	if (IS_ERR(buf)) {
		printk(KERN_ERR "ioctl_write_page_data: "
		       "failed to copy user data\n");
		return PTR_ERR(buf);
	}

	mutex_lock(&spectra_lock);
	result = GLOB_FTL_Page_Write(buf,
		(u64)info.page * IdentifyDeviceData.PageDataSize);
	mutex_unlock(&spectra_lock);

	kfree(buf);
	return result;
}

/* Return how many blocks should be reserved for bad block replacement */
static int get_res_blk_num_bad_blk(void)
{
	return IdentifyDeviceData.wDataBlockNum / 10;
}

/* Return how many blocks should be reserved for OS image */
static int get_res_blk_num_os(void)
{
	u32 res_blks, blk_size;

	blk_size = IdentifyDeviceData.PageDataSize *
		IdentifyDeviceData.PagesPerBlock;

	res_blks = (reserved_mb * 1024 * 1024) / blk_size;

	if ((res_blks < 1) || (res_blks >= IdentifyDeviceData.wDataBlockNum))
		res_blks = 1; /* Reserved 1 block for block table */

	return res_blks;
}

/* Transfer a full request. */
static int do_transfer(struct spectra_nand_dev *tr, struct request *req)
{
	u64 start_addr, addr;
	u32 logical_start_sect, hd_start_sect;
	u32 nsect, hd_sects;
	u32 rsect, tsect = 0;
	char *buf;
	u32 ratio = IdentifyDeviceData.PageDataSize >> 9;

	start_addr = (u64)(blk_rq_pos(req)) << 9;
	/* Add a big enough offset to prevent the OS Image from
	*  being accessed or damaged by file system */
	start_addr += IdentifyDeviceData.PageDataSize *
			IdentifyDeviceData.PagesPerBlock *
			res_blks_os;

	if (req->cmd_type & REQ_FLUSH) {
		if (force_flush_cache()) /* Fail to flush cache */
			return -EIO;
		else
			return 0;
	}

	if (req->cmd_type != REQ_TYPE_FS)
		return -EIO;

	if (blk_rq_pos(req) + blk_rq_cur_sectors(req) > get_capacity(tr->gd)) {
		printk(KERN_ERR "Spectra error: request over the NAND "
			"capacity!sector %d, current_nr_sectors %d, "
			"while capacity is %d\n",
			(int)blk_rq_pos(req),
			blk_rq_cur_sectors(req),
			(int)get_capacity(tr->gd));
		return -EIO;
	}

	logical_start_sect = start_addr >> 9;
	hd_start_sect = logical_start_sect / ratio;
	rsect = logical_start_sect - hd_start_sect * ratio;

	addr = (u64)hd_start_sect * ratio * 512;
	buf = req->buffer;
	nsect = blk_rq_cur_sectors(req);

	if (rsect)
		tsect =  (ratio - rsect) < nsect ? (ratio - rsect) : nsect;

	switch (rq_data_dir(req)) {
	case READ:
		/* Read the first NAND page */
		if (rsect) {
			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
			memcpy(buf, tr->tmp_buf + (rsect << 9), tsect << 9);
			addr += IdentifyDeviceData.PageDataSize;
			buf += tsect << 9;
			nsect -= tsect;
		}

		/* Read the other NAND pages */
		for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
			if (GLOB_FTL_Page_Read(buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
			addr += IdentifyDeviceData.PageDataSize;
			buf += IdentifyDeviceData.PageDataSize;
		}

		/* Read the last NAND pages */
		if (nsect % ratio) {
			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
			memcpy(buf, tr->tmp_buf, (nsect % ratio) << 9);
		}
#if CMD_DMA
		if (glob_ftl_execute_cmds())
			return -EIO;
		else
			return 0;
#endif
		return 0;

	case WRITE:
		/* Write the first NAND page */
		if (rsect) {
			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
			memcpy(tr->tmp_buf + (rsect << 9), buf, tsect << 9);
			if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
			addr += IdentifyDeviceData.PageDataSize;
			buf += tsect << 9;
			nsect -= tsect;
		}

		/* Write the other NAND pages */
		for (hd_sects = nsect / ratio; hd_sects > 0; hd_sects--) {
			if (GLOB_FTL_Page_Write(buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
			addr += IdentifyDeviceData.PageDataSize;
			buf += IdentifyDeviceData.PageDataSize;
		}

		/* Write the last NAND pages */
		if (nsect % ratio) {
			if (GLOB_FTL_Page_Read(tr->tmp_buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
			memcpy(tr->tmp_buf, buf, (nsect % ratio) << 9);
			if (GLOB_FTL_Page_Write(tr->tmp_buf, addr)) {
				printk(KERN_ERR "Error in %s, Line %d\n",
					__FILE__, __LINE__);
				return -EIO;
			}
		}
#if CMD_DMA
		if (glob_ftl_execute_cmds())
			return -EIO;
		else
			return 0;
#endif
		return 0;

	default:
		printk(KERN_NOTICE "Unknown request %u\n", rq_data_dir(req));
		return -EIO;
	}
}

/* This function is copied from drivers/mtd/mtd_blkdevs.c */
static int spectra_trans_thread(void *arg)
{
	struct spectra_nand_dev *tr = arg;
	struct request_queue *rq = tr->queue;
	struct request *req = NULL;

	/* we might get involved when memory gets low, so use PF_MEMALLOC */
	current->flags |= PF_MEMALLOC;

	spin_lock_irq(rq->queue_lock);
	while (!kthread_should_stop()) {
		int res;

		if (!req) {
			req = blk_fetch_request(rq);
			if (!req) {
				set_current_state(TASK_INTERRUPTIBLE);
				spin_unlock_irq(rq->queue_lock);
				schedule();
				spin_lock_irq(rq->queue_lock);
				continue;
			}
		}

		spin_unlock_irq(rq->queue_lock);

		mutex_lock(&spectra_lock);
		res = do_transfer(tr, req);
		mutex_unlock(&spectra_lock);

		spin_lock_irq(rq->queue_lock);

		if (!__blk_end_request_cur(req, res))
			req = NULL;
	}

	if (req)
		__blk_end_request_all(req, -EIO);

	spin_unlock_irq(rq->queue_lock);

	return 0;
}


/* Request function that "handles clustering". */
static void GLOB_SBD_request(struct request_queue *rq)
{
	struct spectra_nand_dev *pdev = rq->queuedata;
	wake_up_process(pdev->thread);
}

static int GLOB_SBD_open(struct block_device *bdev, fmode_t mode)

{
	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);
	return 0;
}

static int GLOB_SBD_release(struct gendisk *disk, fmode_t mode)
{
	int ret;

	nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	mutex_lock(&spectra_lock);
	ret = force_flush_cache();
	mutex_unlock(&spectra_lock);

	return 0;
}

static int GLOB_SBD_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
	geo->heads = 4;
	geo->sectors = 16;
	geo->cylinders = get_capacity(bdev->bd_disk) / (4 * 16);

	nand_dbg_print(NAND_DBG_DEBUG,
		"heads: %d, sectors: %d, cylinders: %d\n",
		geo->heads, geo->sectors, geo->cylinders);

	return 0;
}

int GLOB_SBD_ioctl(struct block_device *bdev, fmode_t mode,
		unsigned int cmd, unsigned long arg)
{
	int ret;

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	switch (cmd) {
	case GLOB_SBD_IOCTL_GC:
		nand_dbg_print(NAND_DBG_DEBUG,
			       "Spectra IOCTL: Garbage Collection "
			       "being performed\n");
		if (PASS != GLOB_FTL_Garbage_Collection())
			return -EFAULT;
		return 0;

	case GLOB_SBD_IOCTL_WL:
		nand_dbg_print(NAND_DBG_DEBUG,
			       "Spectra IOCTL: Static Wear Leveling "
			       "being performed\n");
		if (PASS != GLOB_FTL_Wear_Leveling())
			return -EFAULT;
		return 0;

	case GLOB_SBD_IOCTL_FORMAT:
		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Flash format "
			       "being performed\n");
		if (PASS != GLOB_FTL_Flash_Format())
			return -EFAULT;
		return 0;

	case GLOB_SBD_IOCTL_FLUSH_CACHE:
		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: Cache flush "
			       "being performed\n");
		mutex_lock(&spectra_lock);
		ret = force_flush_cache();
		mutex_unlock(&spectra_lock);
		return ret;

	case GLOB_SBD_IOCTL_COPY_BLK_TABLE:
		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
			       "Copy block table\n");
		if (copy_to_user((void __user *)arg,
			get_blk_table_start_addr(),
			get_blk_table_len()))
			return -EFAULT;
		return 0;

	case GLOB_SBD_IOCTL_COPY_WEAR_LEVELING_TABLE:
		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
			       "Copy wear leveling table\n");
		if (copy_to_user((void __user *)arg,
			get_wear_leveling_table_start_addr(),
			get_wear_leveling_table_len()))
			return -EFAULT;
		return 0;

	case GLOB_SBD_IOCTL_GET_NAND_INFO:
		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
			       "Get NAND info\n");
		if (copy_to_user((void __user *)arg, &IdentifyDeviceData,
			sizeof(IdentifyDeviceData)))
			return -EFAULT;
		return 0;

	case GLOB_SBD_IOCTL_WRITE_DATA:
		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
			       "Write one page data\n");
		return ioctl_write_page_data(arg);

	case GLOB_SBD_IOCTL_READ_DATA:
		nand_dbg_print(NAND_DBG_DEBUG, "Spectra IOCTL: "
			       "Read one page data\n");
		return ioctl_read_page_data(arg);
	}

	return -ENOTTY;
}

static DEFINE_MUTEX(ffsport_mutex);

int GLOB_SBD_unlocked_ioctl(struct block_device *bdev, fmode_t mode,
		unsigned int cmd, unsigned long arg)
{
	int ret;

	mutex_lock(&ffsport_mutex);
	ret = GLOB_SBD_ioctl(bdev, mode, cmd, arg);
	mutex_unlock(&ffsport_mutex);

	return ret;
}

static struct block_device_operations GLOB_SBD_ops = {
	.owner = THIS_MODULE,
	.open = GLOB_SBD_open,
	.release = GLOB_SBD_release,
	.ioctl = GLOB_SBD_unlocked_ioctl,
	.getgeo = GLOB_SBD_getgeo,
};

static int SBD_setup_device(struct spectra_nand_dev *dev, int which)
{
	int res_blks;
	u32 sects;

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	memset(dev, 0, sizeof(struct spectra_nand_dev));

	nand_dbg_print(NAND_DBG_WARN, "Reserved %d blocks "
		"for OS image, %d blocks for bad block replacement.\n",
		get_res_blk_num_os(),
		get_res_blk_num_bad_blk());

	res_blks = get_res_blk_num_bad_blk() + get_res_blk_num_os();

	dev->size = (u64)IdentifyDeviceData.PageDataSize *
		IdentifyDeviceData.PagesPerBlock *
		(IdentifyDeviceData.wDataBlockNum - res_blks);

	res_blks_os = get_res_blk_num_os();

	spin_lock_init(&dev->qlock);

	dev->tmp_buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
	if (!dev->tmp_buf) {
		printk(KERN_ERR "Failed to kmalloc memory in %s Line %d, exit.\n",
			__FILE__, __LINE__);
		goto out_vfree;
	}

	dev->queue = blk_init_queue(GLOB_SBD_request, &dev->qlock);
	if (dev->queue == NULL) {
		printk(KERN_ERR
		       "Spectra: Request queue could not be initialized."
			" Aborting\n ");
		goto out_vfree;
	}
	dev->queue->queuedata = dev;

	/* As Linux block layer doesn't support >4KB hardware sector,  */
	/* Here we force report 512 byte hardware sector size to Kernel */
	blk_queue_logical_block_size(dev->queue, 512);

	blk_queue_flush(dev->queue, REQ_FLUSH);

	dev->thread = kthread_run(spectra_trans_thread, dev, "nand_thd");
	if (IS_ERR(dev->thread)) {
		blk_cleanup_queue(dev->queue);
		unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
		return PTR_ERR(dev->thread);
	}

	dev->gd = alloc_disk(PARTITIONS);
	if (!dev->gd) {
		printk(KERN_ERR
		       "Spectra: Could not allocate disk. Aborting \n ");
		goto out_vfree;
	}
	dev->gd->major = GLOB_SBD_majornum;
	dev->gd->first_minor = which * PARTITIONS;
	dev->gd->fops = &GLOB_SBD_ops;
	dev->gd->queue = dev->queue;
	dev->gd->private_data = dev;
	snprintf(dev->gd->disk_name, 32, "%s%c", GLOB_SBD_NAME, which + 'a');

	sects = dev->size >> 9;
	nand_dbg_print(NAND_DBG_WARN, "Capacity sects: %d\n", sects);
	set_capacity(dev->gd, sects);

	add_disk(dev->gd);

	return 0;
out_vfree:
	return -ENOMEM;
}

/*
static ssize_t show_nand_block_num(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n",
		(int)IdentifyDeviceData.wDataBlockNum);
}

static ssize_t show_nand_pages_per_block(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n",
		(int)IdentifyDeviceData.PagesPerBlock);
}

static ssize_t show_nand_page_size(struct device *dev,
	struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n",
		(int)IdentifyDeviceData.PageDataSize);
}

static DEVICE_ATTR(nand_block_num, 0444, show_nand_block_num, NULL);
static DEVICE_ATTR(nand_pages_per_block, 0444, show_nand_pages_per_block, NULL);
static DEVICE_ATTR(nand_page_size, 0444, show_nand_page_size, NULL);

static void create_sysfs_entry(struct device *dev)
{
	if (device_create_file(dev, &dev_attr_nand_block_num))
		printk(KERN_ERR "Spectra: "
			"failed to create sysfs entry nand_block_num.\n");
	if (device_create_file(dev, &dev_attr_nand_pages_per_block))
		printk(KERN_ERR "Spectra: "
		"failed to create sysfs entry nand_pages_per_block.\n");
	if (device_create_file(dev, &dev_attr_nand_page_size))
		printk(KERN_ERR "Spectra: "
		"failed to create sysfs entry nand_page_size.\n");
}
*/

static void register_spectra_ftl_async(void *unused, async_cookie_t cookie)
{
	int i;

	/* create_sysfs_entry(&dev->dev); */

	if (PASS != GLOB_FTL_IdentifyDevice(&IdentifyDeviceData)) {
		printk(KERN_ERR "Spectra: Unable to Read Flash Device. "
		       "Aborting\n");
		return;
	} else {
		nand_dbg_print(NAND_DBG_WARN, "In GLOB_SBD_init: "
			       "Num blocks=%d, pagesperblock=%d, "
			       "pagedatasize=%d, ECCBytesPerSector=%d\n",
		       (int)IdentifyDeviceData.NumBlocks,
		       (int)IdentifyDeviceData.PagesPerBlock,
		       (int)IdentifyDeviceData.PageDataSize,
		       (int)IdentifyDeviceData.wECCBytesPerSector);
	}

	printk(KERN_ALERT "Spectra: searching block table, please wait ...\n");
	if (GLOB_FTL_Init() != PASS) {
		printk(KERN_ERR "Spectra: Unable to Initialize FTL Layer. "
		       "Aborting\n");
		goto out_ftl_flash_register;
	}
	printk(KERN_ALERT "Spectra: block table has been found.\n");

	GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME);
	if (GLOB_SBD_majornum <= 0) {
		printk(KERN_ERR "Unable to get the major %d for Spectra",
		       GLOB_SBD_majornum);
		goto out_ftl_flash_register;
	}

	for (i = 0; i < NUM_DEVICES; i++)
		if (SBD_setup_device(&nand_device[i], i) == -ENOMEM)
			goto out_blk_register;

	nand_dbg_print(NAND_DBG_DEBUG,
		       "Spectra: module loaded with major number %d\n",
		       GLOB_SBD_majornum);

	return;

out_blk_register:
	unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);
out_ftl_flash_register:
	GLOB_FTL_Cache_Release();
	printk(KERN_ERR "Spectra: Module load failed.\n");
}

int register_spectra_ftl()
{
	async_schedule(register_spectra_ftl_async, NULL);
	return 0;
}
EXPORT_SYMBOL_GPL(register_spectra_ftl);

static int GLOB_SBD_init(void)
{
	/* Set debug output level (0~3) here. 3 is most verbose */
	printk(KERN_ALERT "Spectra: %s\n", GLOB_version);

	mutex_init(&spectra_lock);

	if (PASS != GLOB_FTL_Flash_Init()) {
		printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. "
		       "Aborting\n");
		return -ENODEV;
	}
	return 0;
}

static void __exit GLOB_SBD_exit(void)
{
	int i;

	nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n",
		       __FILE__, __LINE__, __func__);

	for (i = 0; i < NUM_DEVICES; i++) {
		struct spectra_nand_dev *dev = &nand_device[i];
		if (dev->gd) {
			del_gendisk(dev->gd);
			put_disk(dev->gd);
		}
		if (dev->queue)
			blk_cleanup_queue(dev->queue);
		kfree(dev->tmp_buf);
	}

	unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME);

	mutex_lock(&spectra_lock);
	force_flush_cache();
	mutex_unlock(&spectra_lock);

	GLOB_FTL_Cache_Release();

	GLOB_FTL_Flash_Release();

	nand_dbg_print(NAND_DBG_DEBUG,
		       "Spectra FTL module (major number %d) unloaded.\n",
		       GLOB_SBD_majornum);
}

module_init(GLOB_SBD_init);
module_exit(GLOB_SBD_exit);
