// SPDX-License-Identifier: GPL-2.0-only
// Copyright 2014 Cisco Systems, Inc.  All rights reserved.

#include <linux/module.h>
#include <linux/mempool.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/workqueue.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>

#include "snic.h"
#include "snic_fwint.h"

#define PCI_DEVICE_ID_CISCO_SNIC	0x0046

/* Supported devices by snic module */
static struct pci_device_id snic_id_table[] = {
	{PCI_DEVICE(0x1137, PCI_DEVICE_ID_CISCO_SNIC) },
	{ 0, }	/* end of table */
};

unsigned int snic_log_level = 0x0;
module_param(snic_log_level, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(snic_log_level, "bitmask for snic logging levels");

#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
unsigned int snic_trace_max_pages = 16;
module_param(snic_trace_max_pages, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(snic_trace_max_pages,
		"Total allocated memory pages for snic trace buffer");

#endif
unsigned int snic_max_qdepth = SNIC_DFLT_QUEUE_DEPTH;
module_param(snic_max_qdepth, uint, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(snic_max_qdepth, "Queue depth to report for each LUN");

/*
 * snic_slave_alloc : callback function to SCSI Mid Layer, called on
 * scsi device initialization.
 */
static int
snic_slave_alloc(struct scsi_device *sdev)
{
	struct snic_tgt *tgt = starget_to_tgt(scsi_target(sdev));

	if (!tgt || snic_tgt_chkready(tgt))
		return -ENXIO;

	return 0;
}

/*
 * snic_slave_configure : callback function to SCSI Mid Layer, called on
 * scsi device initialization.
 */
static int
snic_slave_configure(struct scsi_device *sdev)
{
	struct snic *snic = shost_priv(sdev->host);
	u32 qdepth = 0, max_ios = 0;
	int tmo = SNIC_DFLT_CMD_TIMEOUT * HZ;

	/* Set Queue Depth */
	max_ios = snic_max_qdepth;
	qdepth = min_t(u32, max_ios, SNIC_MAX_QUEUE_DEPTH);
	scsi_change_queue_depth(sdev, qdepth);

	if (snic->fwinfo.io_tmo > 1)
		tmo = snic->fwinfo.io_tmo * HZ;

	/* FW requires extended timeouts */
	blk_queue_rq_timeout(sdev->request_queue, tmo);

	return 0;
}

static int
snic_change_queue_depth(struct scsi_device *sdev, int qdepth)
{
	struct snic *snic = shost_priv(sdev->host);
	int qsz = 0;

	qsz = min_t(u32, qdepth, SNIC_MAX_QUEUE_DEPTH);
	if (qsz < sdev->queue_depth)
		atomic64_inc(&snic->s_stats.misc.qsz_rampdown);
	else if (qsz > sdev->queue_depth)
		atomic64_inc(&snic->s_stats.misc.qsz_rampup);

	atomic64_set(&snic->s_stats.misc.last_qsz, sdev->queue_depth);

	scsi_change_queue_depth(sdev, qsz);

	return sdev->queue_depth;
}

static const struct scsi_host_template snic_host_template = {
	.module = THIS_MODULE,
	.name = SNIC_DRV_NAME,
	.queuecommand = snic_queuecommand,
	.eh_abort_handler = snic_abort_cmd,
	.eh_device_reset_handler = snic_device_reset,
	.eh_host_reset_handler = snic_host_reset,
	.slave_alloc = snic_slave_alloc,
	.slave_configure = snic_slave_configure,
	.change_queue_depth = snic_change_queue_depth,
	.this_id = -1,
	.cmd_per_lun = SNIC_DFLT_QUEUE_DEPTH,
	.can_queue = SNIC_MAX_IO_REQ,
	.sg_tablesize = SNIC_MAX_SG_DESC_CNT,
	.max_sectors = 0x800,
	.shost_groups = snic_host_groups,
	.track_queue_depth = 1,
	.cmd_size = sizeof(struct snic_internal_io_state),
	.proc_name = "snic_scsi",
};

/*
 * snic_handle_link_event : Handles link events such as link up/down/error
 */
void
snic_handle_link_event(struct snic *snic)
{
	unsigned long flags;

	spin_lock_irqsave(&snic->snic_lock, flags);
	if (snic->stop_link_events) {
		spin_unlock_irqrestore(&snic->snic_lock, flags);

		return;
	}
	spin_unlock_irqrestore(&snic->snic_lock, flags);

	queue_work(snic_glob->event_q, &snic->link_work);
} /* end of snic_handle_link_event */

/*
 * snic_notify_set : sets notification area
 * This notification area is to receive events from fw
 * Note: snic supports only MSIX interrupts, in which we can just call
 *  svnic_dev_notify_set directly
 */
static int
snic_notify_set(struct snic *snic)
{
	int ret = 0;
	enum vnic_dev_intr_mode intr_mode;

	intr_mode = svnic_dev_get_intr_mode(snic->vdev);

	if (intr_mode == VNIC_DEV_INTR_MODE_MSIX) {
		ret = svnic_dev_notify_set(snic->vdev, SNIC_MSIX_ERR_NOTIFY);
	} else {
		SNIC_HOST_ERR(snic->shost,
			      "Interrupt mode should be setup before devcmd notify set %d\n",
			      intr_mode);
		ret = -1;
	}

	return ret;
} /* end of snic_notify_set */

/*
 * snic_dev_wait : polls vnic open status.
 */
static int
snic_dev_wait(struct vnic_dev *vdev,
		int (*start)(struct vnic_dev *, int),
		int (*finished)(struct vnic_dev *, int *),
		int arg)
{
	unsigned long time;
	int ret, done;
	int retry_cnt = 0;

	ret = start(vdev, arg);
	if (ret)
		return ret;

	/*
	 * Wait for func to complete...2 seconds max.
	 *
	 * Sometimes schedule_timeout_uninterruptible take long	time
	 * to wakeup, which results skipping retry. The retry counter
	 * ensures to retry at least two times.
	 */
	time = jiffies + (HZ * 2);
	do {
		ret = finished(vdev, &done);
		if (ret)
			return ret;

		if (done)
			return 0;
		schedule_timeout_uninterruptible(HZ/10);
		++retry_cnt;
	} while (time_after(time, jiffies) || (retry_cnt < 3));

	return -ETIMEDOUT;
} /* end of snic_dev_wait */

/*
 * snic_cleanup: called by snic_remove
 * Stops the snic device, masks all interrupts, Completed CQ entries are
 * drained. Posted WQ/RQ/Copy-WQ entries are cleanup
 */
static int
snic_cleanup(struct snic *snic)
{
	unsigned int i;
	int ret;

	svnic_dev_disable(snic->vdev);
	for (i = 0; i < snic->intr_count; i++)
		svnic_intr_mask(&snic->intr[i]);

	for (i = 0; i < snic->wq_count; i++) {
		ret = svnic_wq_disable(&snic->wq[i]);
		if (ret)
			return ret;
	}

	/* Clean up completed IOs */
	snic_fwcq_cmpl_handler(snic, -1);

	snic_wq_cmpl_handler(snic, -1);

	/* Clean up the IOs that have not completed */
	for (i = 0; i < snic->wq_count; i++)
		svnic_wq_clean(&snic->wq[i], snic_free_wq_buf);

	for (i = 0; i < snic->cq_count; i++)
		svnic_cq_clean(&snic->cq[i]);

	for (i = 0; i < snic->intr_count; i++)
		svnic_intr_clean(&snic->intr[i]);

	/* Cleanup snic specific requests */
	snic_free_all_untagged_reqs(snic);

	/* Cleanup Pending SCSI commands */
	snic_shutdown_scsi_cleanup(snic);

	for (i = 0; i < SNIC_REQ_MAX_CACHES; i++)
		mempool_destroy(snic->req_pool[i]);

	return 0;
} /* end of snic_cleanup */


static void
snic_iounmap(struct snic *snic)
{
	if (snic->bar0.vaddr)
		iounmap(snic->bar0.vaddr);
}

/*
 * snic_vdev_open_done : polls for svnic_dev_open cmd completion.
 */
static int
snic_vdev_open_done(struct vnic_dev *vdev, int *done)
{
	struct snic *snic = svnic_dev_priv(vdev);
	int ret;
	int nretries = 5;

	do {
		ret = svnic_dev_open_done(vdev, done);
		if (ret == 0)
			break;

		SNIC_HOST_INFO(snic->shost, "VNIC_DEV_OPEN Timedout.\n");
	} while (nretries--);

	return ret;
} /* end of snic_vdev_open_done */

/*
 * snic_add_host : registers scsi host with ML
 */
static int
snic_add_host(struct Scsi_Host *shost, struct pci_dev *pdev)
{
	int ret = 0;

	ret = scsi_add_host(shost, &pdev->dev);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "snic: scsi_add_host failed. %d\n",
			      ret);

		return ret;
	}

	SNIC_BUG_ON(shost->work_q != NULL);
	shost->work_q = alloc_ordered_workqueue("scsi_wq_%d", WQ_MEM_RECLAIM,
						shost->host_no);
	if (!shost->work_q) {
		SNIC_HOST_ERR(shost, "Failed to Create ScsiHost wq.\n");

		ret = -ENOMEM;
	}

	return ret;
} /* end of snic_add_host */

static void
snic_del_host(struct Scsi_Host *shost)
{
	if (!shost->work_q)
		return;

	destroy_workqueue(shost->work_q);
	shost->work_q = NULL;
	scsi_remove_host(shost);
}

int
snic_get_state(struct snic *snic)
{
	return atomic_read(&snic->state);
}

void
snic_set_state(struct snic *snic, enum snic_state state)
{
	SNIC_HOST_INFO(snic->shost, "snic state change from %s to %s\n",
		       snic_state_to_str(snic_get_state(snic)),
		       snic_state_to_str(state));

	atomic_set(&snic->state, state);
}

/*
 * snic_probe : Initialize the snic interface.
 */
static int
snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct Scsi_Host *shost;
	struct snic *snic;
	mempool_t *pool;
	unsigned long flags;
	u32 max_ios = 0;
	int ret, i;

	/* Device Information */
	SNIC_INFO("snic device %4x:%4x:%4x:%4x: ",
		  pdev->vendor, pdev->device, pdev->subsystem_vendor,
		  pdev->subsystem_device);

	SNIC_INFO("snic device bus %x: slot %x: fn %x\n",
		  pdev->bus->number, PCI_SLOT(pdev->devfn),
		  PCI_FUNC(pdev->devfn));

	/*
	 * Allocate SCSI Host and setup association between host, and snic
	 */
	shost = scsi_host_alloc(&snic_host_template, sizeof(struct snic));
	if (!shost) {
		SNIC_ERR("Unable to alloc scsi_host\n");
		ret = -ENOMEM;

		goto prob_end;
	}
	snic = shost_priv(shost);
	snic->shost = shost;

	snprintf(snic->name, sizeof(snic->name) - 1, "%s%d", SNIC_DRV_NAME,
		 shost->host_no);

	SNIC_HOST_INFO(shost,
		       "snic%d = %p shost = %p device bus %x: slot %x: fn %x\n",
		       shost->host_no, snic, shost, pdev->bus->number,
		       PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
	/* Per snic debugfs init */
	snic_stats_debugfs_init(snic);
#endif

	/* Setup PCI Resources */
	pci_set_drvdata(pdev, snic);
	snic->pdev = pdev;

	ret = pci_enable_device(pdev);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Cannot enable PCI Resources, aborting : %d\n",
			      ret);

		goto err_free_snic;
	}

	ret = pci_request_regions(pdev, SNIC_DRV_NAME);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Cannot obtain PCI Resources, aborting : %d\n",
			      ret);

		goto err_pci_disable;
	}

	pci_set_master(pdev);

	/*
	 * Query PCI Controller on system for DMA addressing
	 * limitation for the device. Try 43-bit first, and
	 * fail to 32-bit.
	 */
	ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(43));
	if (ret) {
		ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
		if (ret) {
			SNIC_HOST_ERR(shost,
				      "No Usable DMA Configuration, aborting %d\n",
				      ret);
			goto err_rel_regions;
		}
	}

	/* Map vNIC resources from BAR0 */
	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
		SNIC_HOST_ERR(shost, "BAR0 not memory mappable aborting.\n");

		ret = -ENODEV;
		goto err_rel_regions;
	}

	snic->bar0.vaddr = pci_iomap(pdev, 0, 0);
	if (!snic->bar0.vaddr) {
		SNIC_HOST_ERR(shost,
			      "Cannot memory map BAR0 res hdr aborting.\n");

		ret = -ENODEV;
		goto err_rel_regions;
	}

	snic->bar0.bus_addr = pci_resource_start(pdev, 0);
	snic->bar0.len = pci_resource_len(pdev, 0);
	SNIC_BUG_ON(snic->bar0.bus_addr == 0);

	/* Devcmd2 Resource Allocation and Initialization */
	snic->vdev = svnic_dev_alloc_discover(NULL, snic, pdev, &snic->bar0, 1);
	if (!snic->vdev) {
		SNIC_HOST_ERR(shost, "vNIC Resource Discovery Failed.\n");

		ret = -ENODEV;
		goto err_iounmap;
	}

	ret = svnic_dev_cmd_init(snic->vdev, 0);
	if (ret) {
		SNIC_HOST_INFO(shost, "Devcmd2 Init Failed. err = %d\n", ret);

		goto err_vnic_unreg;
	}

	ret = snic_dev_wait(snic->vdev, svnic_dev_open, snic_vdev_open_done, 0);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "vNIC dev open failed, aborting. %d\n",
			      ret);

		goto err_vnic_unreg;
	}

	ret = svnic_dev_init(snic->vdev, 0);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "vNIC dev init failed. aborting. %d\n",
			      ret);

		goto err_dev_close;
	}

	/* Get vNIC information */
	ret = snic_get_vnic_config(snic);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Get vNIC configuration failed, aborting. %d\n",
			      ret);

		goto err_dev_close;
	}

	/* Configure Maximum Outstanding IO reqs */
	max_ios = snic->config.io_throttle_count;
	if (max_ios != SNIC_UCSM_DFLT_THROTTLE_CNT_BLD)
		shost->can_queue = min_t(u32, SNIC_MAX_IO_REQ,
					 max_t(u32, SNIC_MIN_IO_REQ, max_ios));

	snic->max_tag_id = shost->can_queue;

	shost->max_lun = snic->config.luns_per_tgt;
	shost->max_id = SNIC_MAX_TARGET;

	shost->max_cmd_len = MAX_COMMAND_SIZE; /*defined in scsi_cmnd.h*/

	snic_get_res_counts(snic);

	/*
	 * Assumption: Only MSIx is supported
	 */
	ret = snic_set_intr_mode(snic);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Failed to set intr mode aborting. %d\n",
			      ret);

		goto err_dev_close;
	}

	ret = snic_alloc_vnic_res(snic);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Failed to alloc vNIC resources aborting. %d\n",
			      ret);

		goto err_clear_intr;
	}

	/* Initialize specific lists */
	INIT_LIST_HEAD(&snic->list);

	/*
	 * spl_cmd_list for maintaining snic specific cmds
	 * such as EXCH_VER_REQ, REPORT_TARGETS etc
	 */
	INIT_LIST_HEAD(&snic->spl_cmd_list);
	spin_lock_init(&snic->spl_cmd_lock);

	/* initialize all snic locks */
	spin_lock_init(&snic->snic_lock);

	for (i = 0; i < SNIC_WQ_MAX; i++)
		spin_lock_init(&snic->wq_lock[i]);

	for (i = 0; i < SNIC_IO_LOCKS; i++)
		spin_lock_init(&snic->io_req_lock[i]);

	pool = mempool_create_slab_pool(2,
				snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL]);
	if (!pool) {
		SNIC_HOST_ERR(shost, "dflt sgl pool creation failed\n");

		ret = -ENOMEM;
		goto err_free_res;
	}

	snic->req_pool[SNIC_REQ_CACHE_DFLT_SGL] = pool;

	pool = mempool_create_slab_pool(2,
				snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL]);
	if (!pool) {
		SNIC_HOST_ERR(shost, "max sgl pool creation failed\n");

		ret = -ENOMEM;
		goto err_free_dflt_sgl_pool;
	}

	snic->req_pool[SNIC_REQ_CACHE_MAX_SGL] = pool;

	pool = mempool_create_slab_pool(2,
				snic_glob->req_cache[SNIC_REQ_TM_CACHE]);
	if (!pool) {
		SNIC_HOST_ERR(shost, "snic tmreq info pool creation failed.\n");

		ret = -ENOMEM;
		goto err_free_max_sgl_pool;
	}

	snic->req_pool[SNIC_REQ_TM_CACHE] = pool;

	/* Initialize snic state */
	atomic_set(&snic->state, SNIC_INIT);

	atomic_set(&snic->ios_inflight, 0);

	/* Setup notification buffer area */
	ret = snic_notify_set(snic);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Failed to alloc notify buffer aborting. %d\n",
			      ret);

		goto err_free_tmreq_pool;
	}

	spin_lock_irqsave(&snic_glob->snic_list_lock, flags);
	list_add_tail(&snic->list, &snic_glob->snic_list);
	spin_unlock_irqrestore(&snic_glob->snic_list_lock, flags);

	snic_disc_init(&snic->disc);
	INIT_WORK(&snic->tgt_work, snic_handle_tgt_disc);
	INIT_WORK(&snic->disc_work, snic_handle_disc);
	INIT_WORK(&snic->link_work, snic_handle_link);

	/* Enable all queues */
	for (i = 0; i < snic->wq_count; i++)
		svnic_wq_enable(&snic->wq[i]);

	ret = svnic_dev_enable_wait(snic->vdev);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "vNIC dev enable failed w/ error %d\n",
			      ret);

		goto err_vdev_enable;
	}

	ret = snic_request_intr(snic);
	if (ret) {
		SNIC_HOST_ERR(shost, "Unable to request irq. %d\n", ret);

		goto err_req_intr;
	}

	for (i = 0; i < snic->intr_count; i++)
		svnic_intr_unmask(&snic->intr[i]);

	/* Get snic params */
	ret = snic_get_conf(snic);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Failed to get snic io config from FW w err %d\n",
			      ret);

		goto err_get_conf;
	}

	/*
	 * Initialization done with PCI system, hardware, firmware.
	 * Add shost to SCSI
	 */
	ret = snic_add_host(shost, pdev);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "Adding scsi host Failed ... exiting. %d\n",
			      ret);

		goto err_get_conf;
	}

	snic_set_state(snic, SNIC_ONLINE);

	ret = snic_disc_start(snic);
	if (ret) {
		SNIC_HOST_ERR(shost, "snic_probe:Discovery Failed w err = %d\n",
			      ret);

		goto err_get_conf;
	}

	SNIC_HOST_INFO(shost, "SNIC Device Probe Successful.\n");

	return 0;

err_get_conf:
	snic_free_all_untagged_reqs(snic);

	for (i = 0; i < snic->intr_count; i++)
		svnic_intr_mask(&snic->intr[i]);

	snic_free_intr(snic);

err_req_intr:
	svnic_dev_disable(snic->vdev);

err_vdev_enable:
	svnic_dev_notify_unset(snic->vdev);

	for (i = 0; i < snic->wq_count; i++) {
		int rc = 0;

		rc = svnic_wq_disable(&snic->wq[i]);
		if (rc) {
			SNIC_HOST_ERR(shost,
				      "WQ Disable Failed w/ err = %d\n", rc);

			 break;
		}
	}
	snic_del_host(snic->shost);

err_free_tmreq_pool:
	mempool_destroy(snic->req_pool[SNIC_REQ_TM_CACHE]);

err_free_max_sgl_pool:
	mempool_destroy(snic->req_pool[SNIC_REQ_CACHE_MAX_SGL]);

err_free_dflt_sgl_pool:
	mempool_destroy(snic->req_pool[SNIC_REQ_CACHE_DFLT_SGL]);

err_free_res:
	snic_free_vnic_res(snic);

err_clear_intr:
	snic_clear_intr_mode(snic);

err_dev_close:
	svnic_dev_close(snic->vdev);

err_vnic_unreg:
	svnic_dev_unregister(snic->vdev);

err_iounmap:
	snic_iounmap(snic);

err_rel_regions:
	pci_release_regions(pdev);

err_pci_disable:
	pci_disable_device(pdev);

err_free_snic:
#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
	snic_stats_debugfs_remove(snic);
#endif
	scsi_host_put(shost);
	pci_set_drvdata(pdev, NULL);

prob_end:
	SNIC_INFO("sNIC device : bus %d: slot %d: fn %d Registration Failed.\n",
		  pdev->bus->number, PCI_SLOT(pdev->devfn),
		  PCI_FUNC(pdev->devfn));

	return ret;
} /* end of snic_probe */


/*
 * snic_remove : invoked on unbinding the interface to cleanup the
 * resources allocated in snic_probe on initialization.
 */
static void
snic_remove(struct pci_dev *pdev)
{
	struct snic *snic = pci_get_drvdata(pdev);
	unsigned long flags;

	if (!snic) {
		SNIC_INFO("sNIC dev: bus %d slot %d fn %d snic inst is null.\n",
			  pdev->bus->number, PCI_SLOT(pdev->devfn),
			  PCI_FUNC(pdev->devfn));

		return;
	}

	/*
	 * Mark state so that the workqueue thread stops forwarding
	 * received frames and link events. ISR and other threads
	 * that can queue work items will also stop creating work
	 * items on the snic workqueue
	 */
	snic_set_state(snic, SNIC_OFFLINE);
	spin_lock_irqsave(&snic->snic_lock, flags);
	snic->stop_link_events = 1;
	spin_unlock_irqrestore(&snic->snic_lock, flags);

	flush_workqueue(snic_glob->event_q);
	snic_disc_term(snic);

	spin_lock_irqsave(&snic->snic_lock, flags);
	snic->in_remove = 1;
	spin_unlock_irqrestore(&snic->snic_lock, flags);

	/*
	 * This stops the snic device, masks all interrupts, Completed
	 * CQ entries are drained. Posted WQ/RQ/Copy-WQ entries are
	 * cleanup
	 */
	snic_cleanup(snic);

	spin_lock_irqsave(&snic_glob->snic_list_lock, flags);
	list_del(&snic->list);
	spin_unlock_irqrestore(&snic_glob->snic_list_lock, flags);

	snic_tgt_del_all(snic);
#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
	snic_stats_debugfs_remove(snic);
#endif
	snic_del_host(snic->shost);

	svnic_dev_notify_unset(snic->vdev);
	snic_free_intr(snic);
	snic_free_vnic_res(snic);
	snic_clear_intr_mode(snic);
	svnic_dev_close(snic->vdev);
	svnic_dev_unregister(snic->vdev);
	snic_iounmap(snic);
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	pci_set_drvdata(pdev, NULL);

	/* this frees Scsi_Host and snic memory (continuous chunk) */
	scsi_host_put(snic->shost);
} /* end of snic_remove */


struct snic_global *snic_glob;

/*
 * snic_global_data_init: Initialize SNIC Global Data
 * Notes: All the global lists, variables should be part of global data
 * this helps in debugging.
 */
static int
snic_global_data_init(void)
{
	int ret = 0;
	struct kmem_cache *cachep;
	ssize_t len = 0;

	snic_glob = kzalloc(sizeof(*snic_glob), GFP_KERNEL);

	if (!snic_glob) {
		SNIC_ERR("Failed to allocate Global Context.\n");

		ret = -ENOMEM;
		goto gdi_end;
	}

#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
	/* Debugfs related Initialization */
	/* Create debugfs entries for snic */
	snic_debugfs_init();

	/* Trace related Initialization */
	/* Allocate memory for trace buffer */
	ret = snic_trc_init();
	if (ret < 0) {
		SNIC_ERR("Trace buffer init failed, SNIC tracing disabled\n");
		snic_trc_free();
		/* continue even if it fails */
	}

#endif
	INIT_LIST_HEAD(&snic_glob->snic_list);
	spin_lock_init(&snic_glob->snic_list_lock);

	/* Create a cache for allocation of snic_host_req+default size ESGLs */
	len = sizeof(struct snic_req_info);
	len += sizeof(struct snic_host_req) + sizeof(struct snic_dflt_sgl);
	cachep = kmem_cache_create("snic_req_dfltsgl", len, SNIC_SG_DESC_ALIGN,
				   SLAB_HWCACHE_ALIGN, NULL);
	if (!cachep) {
		SNIC_ERR("Failed to create snic default sgl slab\n");
		ret = -ENOMEM;

		goto err_dflt_req_slab;
	}
	snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL] = cachep;

	/* Create a cache for allocation of max size Extended SGLs */
	len = sizeof(struct snic_req_info);
	len += sizeof(struct snic_host_req) + sizeof(struct snic_max_sgl);
	cachep = kmem_cache_create("snic_req_maxsgl", len, SNIC_SG_DESC_ALIGN,
				   SLAB_HWCACHE_ALIGN, NULL);
	if (!cachep) {
		SNIC_ERR("Failed to create snic max sgl slab\n");
		ret = -ENOMEM;

		goto err_max_req_slab;
	}
	snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL] = cachep;

	len = sizeof(struct snic_host_req);
	cachep = kmem_cache_create("snic_req_tm", len, SNIC_SG_DESC_ALIGN,
				   SLAB_HWCACHE_ALIGN, NULL);
	if (!cachep) {
		SNIC_ERR("Failed to create snic tm req slab\n");
		ret = -ENOMEM;

		goto err_tmreq_slab;
	}
	snic_glob->req_cache[SNIC_REQ_TM_CACHE] = cachep;

	/* snic_event queue */
	snic_glob->event_q =
		alloc_ordered_workqueue("%s", WQ_MEM_RECLAIM, "snic_event_wq");
	if (!snic_glob->event_q) {
		SNIC_ERR("snic event queue create failed\n");
		ret = -ENOMEM;

		goto err_eventq;
	}

	return ret;

err_eventq:
	kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_TM_CACHE]);

err_tmreq_slab:
	kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL]);

err_max_req_slab:
	kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL]);

err_dflt_req_slab:
#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
	snic_trc_free();
	snic_debugfs_term();
#endif
	kfree(snic_glob);
	snic_glob = NULL;

gdi_end:
	return ret;
} /* end of snic_glob_init */

/*
 * snic_global_data_cleanup : Frees SNIC Global Data
 */
static void
snic_global_data_cleanup(void)
{
	SNIC_BUG_ON(snic_glob == NULL);

	destroy_workqueue(snic_glob->event_q);
	kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_TM_CACHE]);
	kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_MAX_SGL]);
	kmem_cache_destroy(snic_glob->req_cache[SNIC_REQ_CACHE_DFLT_SGL]);

#ifdef CONFIG_SCSI_SNIC_DEBUG_FS
	/* Freeing Trace Resources */
	snic_trc_free();

	/* Freeing Debugfs Resources */
	snic_debugfs_term();
#endif
	kfree(snic_glob);
	snic_glob = NULL;
} /* end of snic_glob_cleanup */

static struct pci_driver snic_driver = {
	.name = SNIC_DRV_NAME,
	.id_table = snic_id_table,
	.probe = snic_probe,
	.remove = snic_remove,
};

static int __init
snic_init_module(void)
{
	int ret = 0;

#ifndef __x86_64__
	SNIC_INFO("SNIC Driver is supported only for x86_64 platforms!\n");
	add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
#endif

	SNIC_INFO("%s, ver %s\n", SNIC_DRV_DESCRIPTION, SNIC_DRV_VERSION);

	ret = snic_global_data_init();
	if (ret) {
		SNIC_ERR("Failed to Initialize Global Data.\n");

		return ret;
	}

	ret = pci_register_driver(&snic_driver);
	if (ret < 0) {
		SNIC_ERR("PCI driver register error\n");

		goto err_pci_reg;
	}

	return ret;

err_pci_reg:
	snic_global_data_cleanup();

	return ret;
}

static void __exit
snic_cleanup_module(void)
{
	pci_unregister_driver(&snic_driver);
	snic_global_data_cleanup();
}

module_init(snic_init_module);
module_exit(snic_cleanup_module);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION(SNIC_DRV_DESCRIPTION);
MODULE_VERSION(SNIC_DRV_VERSION);
MODULE_DEVICE_TABLE(pci, snic_id_table);
MODULE_AUTHOR("Narsimhulu Musini <nmusini@cisco.com>, "
	      "Sesidhar Baddela <sebaddel@cisco.com>");
