/*
 * 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 = 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 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);
