/*
 * 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 upto 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 = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC);
	if (!buf) {
		printk(KERN_ERR "ioctl_write_page_data: "
		       "failed to allocate memory\n");
		return -ENOMEM;
	}

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

	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 doens'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);
