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

#include <linux/mempool.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/workqueue.h>
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/gfp.h>
#include <scsi/scsi.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_dbg.h>

#include "snic_io.h"
#include "snic.h"

#define snic_cmd_tag(sc)	(scsi_cmd_to_rq(sc)->tag)

const char *snic_state_str[] = {
	[SNIC_INIT]	= "SNIC_INIT",
	[SNIC_ERROR]	= "SNIC_ERROR",
	[SNIC_ONLINE]	= "SNIC_ONLINE",
	[SNIC_OFFLINE]	= "SNIC_OFFLINE",
	[SNIC_FWRESET]	= "SNIC_FWRESET",
};

static const char * const snic_req_state_str[] = {
	[SNIC_IOREQ_NOT_INITED]	= "SNIC_IOREQ_NOT_INITED",
	[SNIC_IOREQ_PENDING]	= "SNIC_IOREQ_PENDING",
	[SNIC_IOREQ_ABTS_PENDING] = "SNIC_IOREQ_ABTS_PENDING",
	[SNIC_IOREQ_ABTS_COMPLETE] = "SNIC_IOREQ_ABTS_COMPLETE",
	[SNIC_IOREQ_LR_PENDING]	= "SNIC_IOREQ_LR_PENDING",
	[SNIC_IOREQ_LR_COMPLETE] = "SNIC_IOREQ_LR_COMPLETE",
	[SNIC_IOREQ_COMPLETE]	= "SNIC_IOREQ_CMD_COMPLETE",
};

/* snic cmd status strings */
static const char * const snic_io_status_str[] = {
	[SNIC_STAT_IO_SUCCESS]	= "SNIC_STAT_IO_SUCCESS", /* 0x0 */
	[SNIC_STAT_INVALID_HDR] = "SNIC_STAT_INVALID_HDR",
	[SNIC_STAT_OUT_OF_RES]	= "SNIC_STAT_OUT_OF_RES",
	[SNIC_STAT_INVALID_PARM] = "SNIC_STAT_INVALID_PARM",
	[SNIC_STAT_REQ_NOT_SUP]	= "SNIC_STAT_REQ_NOT_SUP",
	[SNIC_STAT_IO_NOT_FOUND] = "SNIC_STAT_IO_NOT_FOUND",
	[SNIC_STAT_ABORTED]	= "SNIC_STAT_ABORTED",
	[SNIC_STAT_TIMEOUT]	= "SNIC_STAT_TIMEOUT",
	[SNIC_STAT_SGL_INVALID] = "SNIC_STAT_SGL_INVALID",
	[SNIC_STAT_DATA_CNT_MISMATCH] = "SNIC_STAT_DATA_CNT_MISMATCH",
	[SNIC_STAT_FW_ERR]	= "SNIC_STAT_FW_ERR",
	[SNIC_STAT_ITMF_REJECT] = "SNIC_STAT_ITMF_REJECT",
	[SNIC_STAT_ITMF_FAIL]	= "SNIC_STAT_ITMF_FAIL",
	[SNIC_STAT_ITMF_INCORRECT_LUN] = "SNIC_STAT_ITMF_INCORRECT_LUN",
	[SNIC_STAT_CMND_REJECT] = "SNIC_STAT_CMND_REJECT",
	[SNIC_STAT_DEV_OFFLINE] = "SNIC_STAT_DEV_OFFLINE",
	[SNIC_STAT_NO_BOOTLUN]	= "SNIC_STAT_NO_BOOTLUN",
	[SNIC_STAT_SCSI_ERR]	= "SNIC_STAT_SCSI_ERR",
	[SNIC_STAT_NOT_READY]	= "SNIC_STAT_NOT_READY",
	[SNIC_STAT_FATAL_ERROR]	= "SNIC_STAT_FATAL_ERROR",
};

static void snic_scsi_cleanup(struct snic *, int);

const char *
snic_state_to_str(unsigned int state)
{
	if (state >= ARRAY_SIZE(snic_state_str) || !snic_state_str[state])
		return "Unknown";

	return snic_state_str[state];
}

static const char *
snic_io_status_to_str(unsigned int state)
{
	if ((state >= ARRAY_SIZE(snic_io_status_str)) ||
	     (!snic_io_status_str[state]))
		return "Unknown";

	return snic_io_status_str[state];
}

static const char *
snic_ioreq_state_to_str(unsigned int state)
{
	if (state >= ARRAY_SIZE(snic_req_state_str) ||
			!snic_req_state_str[state])
		return "Unknown";

	return snic_req_state_str[state];
}

static inline spinlock_t *
snic_io_lock_hash(struct snic *snic, struct scsi_cmnd *sc)
{
	u32 hash = snic_cmd_tag(sc) & (SNIC_IO_LOCKS - 1);

	return &snic->io_req_lock[hash];
}

static inline spinlock_t *
snic_io_lock_tag(struct snic *snic, int tag)
{
	return &snic->io_req_lock[tag & (SNIC_IO_LOCKS - 1)];
}

/* snic_release_req_buf : Releases snic_req_info */
static void
snic_release_req_buf(struct snic *snic,
		   struct snic_req_info *rqi,
		   struct scsi_cmnd *sc)
{
	struct snic_host_req *req = rqi_to_req(rqi);

	/* Freeing cmd without marking completion, not okay */
	SNIC_BUG_ON(!((CMD_STATE(sc) == SNIC_IOREQ_COMPLETE) ||
		      (CMD_STATE(sc) == SNIC_IOREQ_ABTS_COMPLETE) ||
		      (CMD_FLAGS(sc) & SNIC_DEV_RST_NOTSUP) ||
		      (CMD_FLAGS(sc) & SNIC_IO_INTERNAL_TERM_ISSUED) ||
		      (CMD_FLAGS(sc) & SNIC_DEV_RST_TERM_ISSUED) ||
		      (CMD_FLAGS(sc) & SNIC_SCSI_CLEANUP) ||
		      (CMD_STATE(sc) == SNIC_IOREQ_LR_COMPLETE)));

	SNIC_SCSI_DBG(snic->shost,
		      "Rel_req:sc %p:tag %x:rqi %p:ioreq %p:abt %p:dr %p: state %s:flags 0x%llx\n",
		      sc, snic_cmd_tag(sc), rqi, rqi->req, rqi->abort_req,
		      rqi->dr_req, snic_ioreq_state_to_str(CMD_STATE(sc)),
		      CMD_FLAGS(sc));

	if (req->u.icmnd.sense_addr)
		dma_unmap_single(&snic->pdev->dev,
				 le64_to_cpu(req->u.icmnd.sense_addr),
				 SCSI_SENSE_BUFFERSIZE,
				 DMA_FROM_DEVICE);

	scsi_dma_unmap(sc);

	snic_req_free(snic, rqi);
} /* end of snic_release_req_buf */

/*
 * snic_queue_icmnd_req : Queues snic_icmnd request
 */
static int
snic_queue_icmnd_req(struct snic *snic,
		     struct snic_req_info *rqi,
		     struct scsi_cmnd *sc,
		     int sg_cnt)
{
	struct scatterlist *sg;
	struct snic_sg_desc *sgd;
	dma_addr_t pa = 0;
	struct scsi_lun lun;
	u16 flags = 0;
	int ret = 0;
	unsigned int i;

	if (sg_cnt) {
		flags = SNIC_ICMND_ESGL;
		sgd = (struct snic_sg_desc *) req_to_sgl(rqi->req);

		for_each_sg(scsi_sglist(sc), sg, sg_cnt, i) {
			sgd->addr = cpu_to_le64(sg_dma_address(sg));
			sgd->len = cpu_to_le32(sg_dma_len(sg));
			sgd->_resvd = 0;
			sgd++;
		}
	}

	pa = dma_map_single(&snic->pdev->dev,
			    sc->sense_buffer,
			    SCSI_SENSE_BUFFERSIZE,
			    DMA_FROM_DEVICE);
	if (dma_mapping_error(&snic->pdev->dev, pa)) {
		SNIC_HOST_ERR(snic->shost,
			      "QIcmnd:PCI Map Failed for sns buf %p tag %x\n",
			      sc->sense_buffer, snic_cmd_tag(sc));
		ret = -ENOMEM;

		return ret;
	}

	int_to_scsilun(sc->device->lun, &lun);
	if (sc->sc_data_direction == DMA_FROM_DEVICE)
		flags |= SNIC_ICMND_RD;
	if (sc->sc_data_direction == DMA_TO_DEVICE)
		flags |= SNIC_ICMND_WR;

	/* Initialize icmnd */
	snic_icmnd_init(rqi->req,
			snic_cmd_tag(sc),
			snic->config.hid, /* hid */
			(ulong) rqi,
			flags, /* command flags */
			rqi->tgt_id,
			lun.scsi_lun,
			sc->cmnd,
			sc->cmd_len,
			scsi_bufflen(sc),
			sg_cnt,
			(ulong) req_to_sgl(rqi->req),
			pa, /* sense buffer pa */
			SCSI_SENSE_BUFFERSIZE);

	atomic64_inc(&snic->s_stats.io.active);
	ret = snic_queue_wq_desc(snic, rqi->req, rqi->req_len);
	if (ret) {
		atomic64_dec(&snic->s_stats.io.active);
		SNIC_HOST_ERR(snic->shost,
			      "QIcmnd: Queuing Icmnd Failed. ret = %d\n",
			      ret);
	} else
		snic_stats_update_active_ios(&snic->s_stats);

	return ret;
} /* end of snic_queue_icmnd_req */

/*
 * snic_issue_scsi_req : Prepares IO request and Issues to FW.
 */
static int
snic_issue_scsi_req(struct snic *snic,
		      struct snic_tgt *tgt,
		      struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	int sg_cnt = 0;
	int ret = 0;
	u32 tag = snic_cmd_tag(sc);
	u64 cmd_trc = 0, cmd_st_flags = 0;
	spinlock_t *io_lock = NULL;
	unsigned long flags;

	CMD_STATE(sc) = SNIC_IOREQ_NOT_INITED;
	CMD_FLAGS(sc) = SNIC_NO_FLAGS;
	sg_cnt = scsi_dma_map(sc);
	if (sg_cnt < 0) {
		SNIC_TRC((u16)snic->shost->host_no, tag, (ulong) sc, 0,
			 sc->cmnd[0], sg_cnt, CMD_STATE(sc));

		SNIC_HOST_ERR(snic->shost, "issue_sc:Failed to map SG List.\n");
		ret = -ENOMEM;

		goto issue_sc_end;
	}

	rqi = snic_req_init(snic, sg_cnt);
	if (!rqi) {
		scsi_dma_unmap(sc);
		ret = -ENOMEM;

		goto issue_sc_end;
	}

	rqi->tgt_id = tgt->id;
	rqi->sc = sc;

	CMD_STATE(sc) = SNIC_IOREQ_PENDING;
	CMD_SP(sc) = (char *) rqi;
	cmd_trc = SNIC_TRC_CMD(sc);
	CMD_FLAGS(sc) |= (SNIC_IO_INITIALIZED | SNIC_IO_ISSUED);
	cmd_st_flags = SNIC_TRC_CMD_STATE_FLAGS(sc);
	io_lock = snic_io_lock_hash(snic, sc);

	/* create wq desc and enqueue it */
	ret = snic_queue_icmnd_req(snic, rqi, sc, sg_cnt);
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "issue_sc: icmnd qing Failed for sc %p, err %d\n",
			      sc, ret);

		spin_lock_irqsave(io_lock, flags);
		rqi = (struct snic_req_info *) CMD_SP(sc);
		CMD_SP(sc) = NULL;
		CMD_STATE(sc) = SNIC_IOREQ_COMPLETE;
		CMD_FLAGS(sc) &= ~SNIC_IO_ISSUED; /* turn off the flag */
		spin_unlock_irqrestore(io_lock, flags);

		if (rqi)
			snic_release_req_buf(snic, rqi, sc);

		SNIC_TRC(snic->shost->host_no, tag, (ulong) sc, 0, 0, 0,
			 SNIC_TRC_CMD_STATE_FLAGS(sc));
	} else {
		u32 io_sz = scsi_bufflen(sc) >> 9;
		u32 qtime = jiffies - rqi->start_time;
		struct snic_io_stats *iostats = &snic->s_stats.io;

		if (io_sz > atomic64_read(&iostats->max_io_sz))
			atomic64_set(&iostats->max_io_sz, io_sz);

		if (qtime > atomic64_read(&iostats->max_qtime))
			atomic64_set(&iostats->max_qtime, qtime);

		SNIC_SCSI_DBG(snic->shost,
			      "issue_sc:sc %p, tag %d queued to WQ.\n",
			      sc, tag);

		SNIC_TRC(snic->shost->host_no, tag, (ulong) sc, (ulong) rqi,
			 sg_cnt, cmd_trc, cmd_st_flags);
	}

issue_sc_end:

	return ret;
} /* end of snic_issue_scsi_req */


/*
 * snic_queuecommand
 * Routine to send a scsi cdb to LLD
 * Called with host_lock held and interrupts disabled
 */
int
snic_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *sc)
{
	struct snic_tgt *tgt = NULL;
	struct snic *snic = shost_priv(shost);
	int ret;

	tgt = starget_to_tgt(scsi_target(sc->device));
	ret = snic_tgt_chkready(tgt);
	if (ret) {
		SNIC_HOST_ERR(shost, "Tgt %p id %d Not Ready.\n", tgt, tgt->id);
		atomic64_inc(&snic->s_stats.misc.tgt_not_rdy);
		sc->result = ret;
		scsi_done(sc);

		return 0;
	}

	if (snic_get_state(snic) != SNIC_ONLINE) {
		SNIC_HOST_ERR(shost, "snic state is %s\n",
			      snic_state_str[snic_get_state(snic)]);

		return SCSI_MLQUEUE_HOST_BUSY;
	}
	atomic_inc(&snic->ios_inflight);

	SNIC_SCSI_DBG(shost, "sc %p Tag %d (sc %0x) lun %lld in snic_qcmd\n",
		      sc, snic_cmd_tag(sc), sc->cmnd[0], sc->device->lun);

	ret = snic_issue_scsi_req(snic, tgt, sc);
	if (ret) {
		SNIC_HOST_ERR(shost, "Failed to Q, Scsi Req w/ err %d.\n", ret);
		ret = SCSI_MLQUEUE_HOST_BUSY;
	}

	atomic_dec(&snic->ios_inflight);

	return ret;
} /* end of snic_queuecommand */

/*
 * snic_process_abts_pending_state:
 * caller should hold IO lock
 */
static void
snic_proc_tmreq_pending_state(struct snic *snic,
			      struct scsi_cmnd *sc,
			      u8 cmpl_status)
{
	int state = CMD_STATE(sc);

	if (state == SNIC_IOREQ_ABTS_PENDING)
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_PENDING;
	else if (state == SNIC_IOREQ_LR_PENDING)
		CMD_FLAGS(sc) |= SNIC_DEV_RST_PENDING;
	else
		SNIC_BUG_ON(1);

	switch (cmpl_status) {
	case SNIC_STAT_IO_SUCCESS:
		CMD_FLAGS(sc) |= SNIC_IO_DONE;
		break;

	case SNIC_STAT_ABORTED:
		CMD_FLAGS(sc) |= SNIC_IO_ABORTED;
		break;

	default:
		SNIC_BUG_ON(1);
	}
}

/*
 * snic_process_io_failed_state:
 * Processes IO's error states
 */
static void
snic_process_io_failed_state(struct snic *snic,
			     struct snic_icmnd_cmpl *icmnd_cmpl,
			     struct scsi_cmnd *sc,
			     u8 cmpl_stat)
{
	int res = 0;

	switch (cmpl_stat) {
	case SNIC_STAT_TIMEOUT:		/* Req was timedout */
		atomic64_inc(&snic->s_stats.misc.io_tmo);
		res = DID_TIME_OUT;
		break;

	case SNIC_STAT_ABORTED:		/* Req was aborted */
		atomic64_inc(&snic->s_stats.misc.io_aborted);
		res = DID_ABORT;
		break;

	case SNIC_STAT_DATA_CNT_MISMATCH:/* Recv/Sent more/less data than exp */
		atomic64_inc(&snic->s_stats.misc.data_cnt_mismat);
		scsi_set_resid(sc, le32_to_cpu(icmnd_cmpl->resid));
		res = DID_ERROR;
		break;

	case SNIC_STAT_OUT_OF_RES: /* Out of resources to complete request */
		atomic64_inc(&snic->s_stats.fw.out_of_res);
		res = DID_REQUEUE;
		break;

	case SNIC_STAT_IO_NOT_FOUND:	/* Requested I/O was not found */
		atomic64_inc(&snic->s_stats.io.io_not_found);
		res = DID_ERROR;
		break;

	case SNIC_STAT_SGL_INVALID:	/* Req was aborted to due to sgl error*/
		atomic64_inc(&snic->s_stats.misc.sgl_inval);
		res = DID_ERROR;
		break;

	case SNIC_STAT_FW_ERR:		/* Req terminated due to FW Error */
		atomic64_inc(&snic->s_stats.fw.io_errs);
		res = DID_ERROR;
		break;

	case SNIC_STAT_SCSI_ERR:	/* FW hits SCSI Error */
		atomic64_inc(&snic->s_stats.fw.scsi_errs);
		break;

	case SNIC_STAT_NOT_READY:	/* XPT yet to initialize */
	case SNIC_STAT_DEV_OFFLINE:	/* Device offline */
		res = DID_NO_CONNECT;
		break;

	case SNIC_STAT_INVALID_HDR:	/* Hdr contains invalid data */
	case SNIC_STAT_INVALID_PARM:	/* Some param in req is invalid */
	case SNIC_STAT_REQ_NOT_SUP:	/* Req type is not supported */
	case SNIC_STAT_CMND_REJECT:	/* Req rejected */
	case SNIC_STAT_FATAL_ERROR:	/* XPT Error */
	default:
		SNIC_SCSI_DBG(snic->shost,
			      "Invalid Hdr/Param or Req Not Supported or Cmnd Rejected or Device Offline. or Unknown\n");
		res = DID_ERROR;
		break;
	}

	SNIC_HOST_ERR(snic->shost, "fw returns failed status %s flags 0x%llx\n",
		      snic_io_status_to_str(cmpl_stat), CMD_FLAGS(sc));

	/* Set sc->result */
	sc->result = (res << 16) | icmnd_cmpl->scsi_status;
} /* end of snic_process_io_failed_state */

/*
 * snic_tmreq_pending : is task management in progress.
 */
static int
snic_tmreq_pending(struct scsi_cmnd *sc)
{
	int state = CMD_STATE(sc);

	return ((state == SNIC_IOREQ_ABTS_PENDING) ||
			(state == SNIC_IOREQ_LR_PENDING));
}

/*
 * snic_process_icmnd_cmpl_status:
 * Caller should hold io_lock
 */
static int
snic_process_icmnd_cmpl_status(struct snic *snic,
			       struct snic_icmnd_cmpl *icmnd_cmpl,
			       u8 cmpl_stat,
			       struct scsi_cmnd *sc)
{
	u8 scsi_stat = icmnd_cmpl->scsi_status;
	int ret = 0;

	/* Mark the IO as complete */
	CMD_STATE(sc) = SNIC_IOREQ_COMPLETE;

	if (likely(cmpl_stat == SNIC_STAT_IO_SUCCESS)) {
		sc->result = (DID_OK << 16) | scsi_stat;

		/* Update SCSI Cmd with resid value */
		scsi_set_resid(sc, le32_to_cpu(icmnd_cmpl->resid));

		if (icmnd_cmpl->flags & SNIC_ICMND_CMPL_UNDR_RUN)
			atomic64_inc(&snic->s_stats.misc.io_under_run);

		if (icmnd_cmpl->scsi_status == SAM_STAT_TASK_SET_FULL)
			atomic64_inc(&snic->s_stats.misc.qfull);

		ret = 0;
	} else {
		snic_process_io_failed_state(snic, icmnd_cmpl, sc, cmpl_stat);
		atomic64_inc(&snic->s_stats.io.fail);
		SNIC_HOST_ERR(snic->shost,
			      "icmnd_cmpl: IO Failed : Hdr Status %s flags 0x%llx\n",
			      snic_io_status_to_str(cmpl_stat), CMD_FLAGS(sc));
		ret = 1;
	}

	return ret;
} /* end of snic_process_icmnd_cmpl_status */


/*
 * snic_icmnd_cmpl_handler
 * Routine to handle icmnd completions
 */
static void
snic_icmnd_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
{
	u8 typ, hdr_stat;
	u32 cmnd_id, hid;
	ulong ctx;
	struct scsi_cmnd *sc = NULL;
	struct snic_icmnd_cmpl *icmnd_cmpl = NULL;
	struct snic_host_req *req = NULL;
	struct snic_req_info *rqi = NULL;
	unsigned long flags, start_time;
	spinlock_t *io_lock;
	u8 sc_stat = 0;

	snic_io_hdr_dec(&fwreq->hdr, &typ, &hdr_stat, &cmnd_id, &hid, &ctx);
	icmnd_cmpl = &fwreq->u.icmnd_cmpl;
	sc_stat = icmnd_cmpl->scsi_status;

	SNIC_SCSI_DBG(snic->shost,
		      "Icmnd_cmpl: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x,i ctx = %lx\n",
		      typ, hdr_stat, cmnd_id, hid, ctx);

	if (cmnd_id >= snic->max_tag_id) {
		SNIC_HOST_ERR(snic->shost,
			      "Icmnd_cmpl:Tag Error:Out of Range Tag %d, hdr status = %s\n",
			      cmnd_id, snic_io_status_to_str(hdr_stat));
		return;
	}

	sc = scsi_host_find_tag(snic->shost, cmnd_id);
	WARN_ON_ONCE(!sc);

	if (!sc) {
		atomic64_inc(&snic->s_stats.io.sc_null);
		SNIC_HOST_ERR(snic->shost,
			      "Icmnd_cmpl: Scsi Cmnd Not found, sc = NULL Hdr Status = %s tag = 0x%x fwreq = 0x%p\n",
			      snic_io_status_to_str(hdr_stat),
			      cmnd_id,
			      fwreq);

		SNIC_TRC(snic->shost->host_no, cmnd_id, 0,
			 ((u64)hdr_stat << 16 |
			  (u64)sc_stat << 8 | (u64)icmnd_cmpl->flags),
			 (ulong) fwreq, le32_to_cpu(icmnd_cmpl->resid), ctx);

		return;
	}

	io_lock = snic_io_lock_hash(snic, sc);

	spin_lock_irqsave(io_lock, flags);
	rqi = (struct snic_req_info *) CMD_SP(sc);
	SNIC_SCSI_DBG(snic->shost,
		      "Icmnd_cmpl:lun %lld sc %p cmd %xtag %d flags 0x%llx rqi %p\n",
		      sc->device->lun, sc, sc->cmnd[0], snic_cmd_tag(sc),
		      CMD_FLAGS(sc), rqi);

	if (CMD_FLAGS(sc) & SNIC_HOST_RESET_CMD_TERM) {
		spin_unlock_irqrestore(io_lock, flags);

		return;
	}

	SNIC_BUG_ON(rqi != (struct snic_req_info *)ctx);
	WARN_ON_ONCE(req);
	if (!rqi) {
		atomic64_inc(&snic->s_stats.io.req_null);
		CMD_FLAGS(sc) |= SNIC_IO_REQ_NULL;
		spin_unlock_irqrestore(io_lock, flags);

		SNIC_HOST_ERR(snic->shost,
			      "Icmnd_cmpl:Host Req Not Found(null), Hdr Status %s, Tag 0x%x, sc 0x%p flags 0x%llx\n",
			      snic_io_status_to_str(hdr_stat),
			      cmnd_id, sc, CMD_FLAGS(sc));
		return;
	}

	rqi = (struct snic_req_info *) ctx;
	start_time = rqi->start_time;

	/* firmware completed the io */
	rqi->io_cmpl = 1;

	/*
	 * if SCSI-ML has already issued abort on this command,
	 * ignore completion of the IO. The abts path will clean it up
	 */
	if (unlikely(snic_tmreq_pending(sc))) {
		snic_proc_tmreq_pending_state(snic, sc, hdr_stat);
		spin_unlock_irqrestore(io_lock, flags);

		snic_stats_update_io_cmpl(&snic->s_stats);

		/* Expected value is SNIC_STAT_ABORTED */
		if (likely(hdr_stat == SNIC_STAT_ABORTED))
			return;

		SNIC_SCSI_DBG(snic->shost,
			      "icmnd_cmpl:TM Req Pending(%s), Hdr Status %s sc 0x%p scsi status %x resid %d flags 0x%llx\n",
			      snic_ioreq_state_to_str(CMD_STATE(sc)),
			      snic_io_status_to_str(hdr_stat),
			      sc, sc_stat, le32_to_cpu(icmnd_cmpl->resid),
			      CMD_FLAGS(sc));

		SNIC_TRC(snic->shost->host_no, cmnd_id, (ulong) sc,
			 jiffies_to_msecs(jiffies - start_time), (ulong) fwreq,
			 SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));

		return;
	}

	if (snic_process_icmnd_cmpl_status(snic, icmnd_cmpl, hdr_stat, sc)) {
		scsi_print_command(sc);
		SNIC_HOST_ERR(snic->shost,
			      "icmnd_cmpl:IO Failed, sc 0x%p Tag %d Cmd %x Hdr Status %s flags 0x%llx\n",
			      sc, sc->cmnd[0], cmnd_id,
			      snic_io_status_to_str(hdr_stat), CMD_FLAGS(sc));
	}

	/* Break link with the SCSI Command */
	CMD_SP(sc) = NULL;
	CMD_FLAGS(sc) |= SNIC_IO_DONE;

	spin_unlock_irqrestore(io_lock, flags);

	/* For now, consider only successful IO. */
	snic_calc_io_process_time(snic, rqi);

	snic_release_req_buf(snic, rqi, sc);

	SNIC_TRC(snic->shost->host_no, cmnd_id, (ulong) sc,
		 jiffies_to_msecs(jiffies - start_time), (ulong) fwreq,
		 SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));


	scsi_done(sc);

	snic_stats_update_io_cmpl(&snic->s_stats);
} /* end of snic_icmnd_cmpl_handler */

static void
snic_proc_dr_cmpl_locked(struct snic *snic,
			 struct snic_fw_req *fwreq,
			 u8 cmpl_stat,
			 u32 cmnd_id,
			 struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = (struct snic_req_info *) CMD_SP(sc);
	u32 start_time = rqi->start_time;

	CMD_LR_STATUS(sc) = cmpl_stat;

	SNIC_SCSI_DBG(snic->shost, "itmf_cmpl: Cmd State = %s\n",
		      snic_ioreq_state_to_str(CMD_STATE(sc)));

	if (CMD_STATE(sc) == SNIC_IOREQ_ABTS_PENDING) {
		CMD_FLAGS(sc) |= SNIC_DEV_RST_ABTS_PENDING;

		SNIC_TRC(snic->shost->host_no, cmnd_id, (ulong) sc,
			 jiffies_to_msecs(jiffies - start_time),
			 (ulong) fwreq, 0, SNIC_TRC_CMD_STATE_FLAGS(sc));

		SNIC_SCSI_DBG(snic->shost,
			      "itmf_cmpl: Terminate Pending Dev Reset Cmpl Recvd.id %x, status %s flags 0x%llx\n",
			      (int)(cmnd_id & SNIC_TAG_MASK),
			      snic_io_status_to_str(cmpl_stat),
			      CMD_FLAGS(sc));

		return;
	}


	if (CMD_FLAGS(sc) & SNIC_DEV_RST_TIMEDOUT) {
		SNIC_TRC(snic->shost->host_no, cmnd_id, (ulong) sc,
			 jiffies_to_msecs(jiffies - start_time),
			 (ulong) fwreq, 0, SNIC_TRC_CMD_STATE_FLAGS(sc));

		SNIC_SCSI_DBG(snic->shost,
			      "itmf_cmpl:Dev Reset Completion Received after timeout. id %d cmpl status %s flags 0x%llx\n",
			      (int)(cmnd_id & SNIC_TAG_MASK),
			      snic_io_status_to_str(cmpl_stat),
			      CMD_FLAGS(sc));

		return;
	}

	CMD_STATE(sc) = SNIC_IOREQ_LR_COMPLETE;
	CMD_FLAGS(sc) |= SNIC_DEV_RST_DONE;

	SNIC_SCSI_DBG(snic->shost,
		      "itmf_cmpl:Dev Reset Cmpl Recvd id %d cmpl status %s flags 0x%llx\n",
		      (int)(cmnd_id & SNIC_TAG_MASK),
		      snic_io_status_to_str(cmpl_stat),
		      CMD_FLAGS(sc));

	if (rqi->dr_done)
		complete(rqi->dr_done);
} /* end of snic_proc_dr_cmpl_locked */

/*
 * snic_update_abort_stats : Updates abort stats based on completion status.
 */
static void
snic_update_abort_stats(struct snic *snic, u8 cmpl_stat)
{
	struct snic_abort_stats *abt_stats = &snic->s_stats.abts;

	SNIC_SCSI_DBG(snic->shost, "Updating Abort stats.\n");

	switch (cmpl_stat) {
	case  SNIC_STAT_IO_SUCCESS:
		break;

	case SNIC_STAT_TIMEOUT:
		atomic64_inc(&abt_stats->fw_tmo);
		break;

	case SNIC_STAT_IO_NOT_FOUND:
		atomic64_inc(&abt_stats->io_not_found);
		break;

	default:
		atomic64_inc(&abt_stats->fail);
		break;
	}
}

static int
snic_process_itmf_cmpl(struct snic *snic,
		       struct snic_fw_req *fwreq,
		       u32 cmnd_id,
		       u8 cmpl_stat,
		       struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	u32 tm_tags = 0;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	u32 start_time = 0;
	int ret = 0;

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);
	if (CMD_FLAGS(sc) & SNIC_HOST_RESET_CMD_TERM) {
		spin_unlock_irqrestore(io_lock, flags);

		return ret;
	}
	rqi = (struct snic_req_info *) CMD_SP(sc);
	WARN_ON_ONCE(!rqi);

	if (!rqi) {
		atomic64_inc(&snic->s_stats.io.req_null);
		spin_unlock_irqrestore(io_lock, flags);
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_TERM_REQ_NULL;
		SNIC_HOST_ERR(snic->shost,
			      "itmf_cmpl: rqi is null,Hdr stat = %s Tag = 0x%x sc = 0x%p flags 0x%llx\n",
			      snic_io_status_to_str(cmpl_stat), cmnd_id, sc,
			      CMD_FLAGS(sc));

		return ret;
	}

	/* Extract task management flags */
	tm_tags = cmnd_id & ~(SNIC_TAG_MASK);

	start_time = rqi->start_time;
	cmnd_id &= (SNIC_TAG_MASK);

	switch (tm_tags) {
	case SNIC_TAG_ABORT:
		/* Abort only issued on cmd */
		snic_update_abort_stats(snic, cmpl_stat);

		if (CMD_STATE(sc) != SNIC_IOREQ_ABTS_PENDING) {
			/* This is a late completion. Ignore it. */
			ret = -1;
			spin_unlock_irqrestore(io_lock, flags);
			break;
		}

		CMD_STATE(sc) = SNIC_IOREQ_ABTS_COMPLETE;
		CMD_ABTS_STATUS(sc) = cmpl_stat;
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_TERM_DONE;

		SNIC_SCSI_DBG(snic->shost,
			      "itmf_cmpl:Abort Cmpl Recvd.Tag 0x%x Status %s flags 0x%llx\n",
			      cmnd_id,
			      snic_io_status_to_str(cmpl_stat),
			      CMD_FLAGS(sc));

		/*
		 * If scsi_eh thread is blocked waiting for abts complete,
		 * signal completion to it. IO will be cleaned in the thread,
		 * else clean it in this context.
		 */
		if (rqi->abts_done) {
			complete(rqi->abts_done);
			spin_unlock_irqrestore(io_lock, flags);

			break; /* jump out */
		}

		CMD_SP(sc) = NULL;
		sc->result = (DID_ERROR << 16);
		SNIC_SCSI_DBG(snic->shost,
			      "itmf_cmpl: Completing IO. sc %p flags 0x%llx\n",
			      sc, CMD_FLAGS(sc));

		spin_unlock_irqrestore(io_lock, flags);

		snic_release_req_buf(snic, rqi, sc);

		SNIC_TRC(snic->shost->host_no, cmnd_id, (ulong) sc,
			 jiffies_to_msecs(jiffies - start_time),
			 (ulong) fwreq, SNIC_TRC_CMD(sc),
			 SNIC_TRC_CMD_STATE_FLAGS(sc));

		scsi_done(sc);

		break;

	case SNIC_TAG_DEV_RST:
	case SNIC_TAG_DEV_RST | SNIC_TAG_IOCTL_DEV_RST:
		snic_proc_dr_cmpl_locked(snic, fwreq, cmpl_stat, cmnd_id, sc);
		spin_unlock_irqrestore(io_lock, flags);
		ret = 0;

		break;

	case SNIC_TAG_ABORT | SNIC_TAG_DEV_RST:
		/* Abort and terminate completion of device reset req */

		CMD_STATE(sc) = SNIC_IOREQ_ABTS_COMPLETE;
		CMD_ABTS_STATUS(sc) = cmpl_stat;
		CMD_FLAGS(sc) |= SNIC_DEV_RST_DONE;

		SNIC_SCSI_DBG(snic->shost,
			      "itmf_cmpl:dev reset abts cmpl recvd. id %d status %s flags 0x%llx\n",
			      cmnd_id, snic_io_status_to_str(cmpl_stat),
			      CMD_FLAGS(sc));

		if (rqi->abts_done)
			complete(rqi->abts_done);

		spin_unlock_irqrestore(io_lock, flags);

		break;

	default:
		spin_unlock_irqrestore(io_lock, flags);
		SNIC_HOST_ERR(snic->shost,
			      "itmf_cmpl: Unknown TM tag bit 0x%x\n", tm_tags);

		SNIC_HOST_ERR(snic->shost,
			      "itmf_cmpl:Unexpected itmf io stat %s Tag = 0x%x flags 0x%llx\n",
			      snic_ioreq_state_to_str(CMD_STATE(sc)),
			      cmnd_id,
			      CMD_FLAGS(sc));
		ret = -1;
		SNIC_BUG_ON(1);

		break;
	}

	return ret;
} /* end of snic_process_itmf_cmpl_status */

/*
 * snic_itmf_cmpl_handler.
 * Routine to handle itmf completions.
 */
static void
snic_itmf_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
{
	struct scsi_cmnd  *sc = NULL;
	struct snic_req_info *rqi = NULL;
	struct snic_itmf_cmpl *itmf_cmpl = NULL;
	ulong ctx;
	u32 cmnd_id;
	u32 hid;
	u8 typ;
	u8 hdr_stat;

	snic_io_hdr_dec(&fwreq->hdr, &typ, &hdr_stat, &cmnd_id, &hid, &ctx);
	SNIC_SCSI_DBG(snic->shost,
		      "Itmf_cmpl: %s: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x,ctx = %lx\n",
		      __func__, typ, hdr_stat, cmnd_id, hid, ctx);

	itmf_cmpl = &fwreq->u.itmf_cmpl;
	SNIC_SCSI_DBG(snic->shost,
		      "Itmf_cmpl: nterm %u , flags 0x%x\n",
		      le32_to_cpu(itmf_cmpl->nterminated), itmf_cmpl->flags);

	/* spl case, dev reset issued through ioctl */
	if (cmnd_id & SNIC_TAG_IOCTL_DEV_RST) {
		rqi = (struct snic_req_info *) ctx;
		sc = rqi->sc;

		goto ioctl_dev_rst;
	}

	if ((cmnd_id & SNIC_TAG_MASK) >= snic->max_tag_id) {
		SNIC_HOST_ERR(snic->shost,
			      "Itmf_cmpl: Tag 0x%x out of Range,HdrStat %s\n",
			      cmnd_id, snic_io_status_to_str(hdr_stat));
		SNIC_BUG_ON(1);

		return;
	}

	sc = scsi_host_find_tag(snic->shost, cmnd_id & SNIC_TAG_MASK);
	WARN_ON_ONCE(!sc);

ioctl_dev_rst:
	if (!sc) {
		atomic64_inc(&snic->s_stats.io.sc_null);
		SNIC_HOST_ERR(snic->shost,
			      "Itmf_cmpl: sc is NULL - Hdr Stat %s Tag 0x%x\n",
			      snic_io_status_to_str(hdr_stat), cmnd_id);

		return;
	}

	snic_process_itmf_cmpl(snic, fwreq, cmnd_id, hdr_stat, sc);
} /* end of snic_itmf_cmpl_handler */



static void
snic_hba_reset_scsi_cleanup(struct snic *snic, struct scsi_cmnd *sc)
{
	struct snic_stats *st = &snic->s_stats;
	long act_ios = 0, act_fwreqs = 0;

	SNIC_SCSI_DBG(snic->shost, "HBA Reset scsi cleanup.\n");
	snic_scsi_cleanup(snic, snic_cmd_tag(sc));

	/* Update stats on pending IOs */
	act_ios = atomic64_read(&st->io.active);
	atomic64_add(act_ios, &st->io.compl);
	atomic64_sub(act_ios, &st->io.active);

	act_fwreqs = atomic64_read(&st->fw.actv_reqs);
	atomic64_sub(act_fwreqs, &st->fw.actv_reqs);
}

/*
 * snic_hba_reset_cmpl_handler :
 *
 * Notes :
 * 1. Cleanup all the scsi cmds, release all snic specific cmds
 * 2. Issue Report Targets in case of SAN targets
 */
static int
snic_hba_reset_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
{
	ulong ctx;
	u32 cmnd_id;
	u32 hid;
	u8 typ;
	u8 hdr_stat;
	struct scsi_cmnd *sc = NULL;
	struct snic_req_info *rqi = NULL;
	spinlock_t *io_lock = NULL;
	unsigned long flags, gflags;
	int ret = 0;

	snic_io_hdr_dec(&fwreq->hdr, &typ, &hdr_stat, &cmnd_id, &hid, &ctx);
	SNIC_HOST_INFO(snic->shost,
		       "reset_cmpl:Tag %d ctx %lx cmpl status %s HBA Reset Completion received.\n",
		       cmnd_id, ctx, snic_io_status_to_str(hdr_stat));

	SNIC_SCSI_DBG(snic->shost,
		      "reset_cmpl: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x, ctx = %lx\n",
		      typ, hdr_stat, cmnd_id, hid, ctx);

	/* spl case, host reset issued through ioctl */
	if (cmnd_id == SCSI_NO_TAG) {
		rqi = (struct snic_req_info *) ctx;
		SNIC_HOST_INFO(snic->shost,
			       "reset_cmpl:Tag %d ctx %lx cmpl stat %s\n",
			       cmnd_id, ctx, snic_io_status_to_str(hdr_stat));
		sc = rqi->sc;

		goto ioctl_hba_rst;
	}

	if (cmnd_id >= snic->max_tag_id) {
		SNIC_HOST_ERR(snic->shost,
			      "reset_cmpl: Tag 0x%x out of Range,HdrStat %s\n",
			      cmnd_id, snic_io_status_to_str(hdr_stat));
		SNIC_BUG_ON(1);

		return 1;
	}

	sc = scsi_host_find_tag(snic->shost, cmnd_id);
ioctl_hba_rst:
	if (!sc) {
		atomic64_inc(&snic->s_stats.io.sc_null);
		SNIC_HOST_ERR(snic->shost,
			      "reset_cmpl: sc is NULL - Hdr Stat %s Tag 0x%x\n",
			      snic_io_status_to_str(hdr_stat), cmnd_id);
		ret = 1;

		return ret;
	}

	SNIC_HOST_INFO(snic->shost,
		       "reset_cmpl: sc %p rqi %p Tag %d flags 0x%llx\n",
		       sc, rqi, cmnd_id, CMD_FLAGS(sc));

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);

	if (!snic->remove_wait) {
		spin_unlock_irqrestore(io_lock, flags);
		SNIC_HOST_ERR(snic->shost,
			      "reset_cmpl:host reset completed after timeout\n");
		ret = 1;

		return ret;
	}

	rqi = (struct snic_req_info *) CMD_SP(sc);
	WARN_ON_ONCE(!rqi);

	if (!rqi) {
		atomic64_inc(&snic->s_stats.io.req_null);
		spin_unlock_irqrestore(io_lock, flags);
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_TERM_REQ_NULL;
		SNIC_HOST_ERR(snic->shost,
			      "reset_cmpl: rqi is null,Hdr stat %s Tag 0x%x sc 0x%p flags 0x%llx\n",
			      snic_io_status_to_str(hdr_stat), cmnd_id, sc,
			      CMD_FLAGS(sc));

		ret = 1;

		return ret;
	}
	/* stats */
	spin_unlock_irqrestore(io_lock, flags);

	/* scsi cleanup */
	snic_hba_reset_scsi_cleanup(snic, sc);

	SNIC_BUG_ON(snic_get_state(snic) != SNIC_OFFLINE &&
		    snic_get_state(snic) != SNIC_FWRESET);

	/* Careful locking between snic_lock and io lock */
	spin_lock_irqsave(io_lock, flags);
	spin_lock_irqsave(&snic->snic_lock, gflags);
	if (snic_get_state(snic) == SNIC_FWRESET)
		snic_set_state(snic, SNIC_ONLINE);
	spin_unlock_irqrestore(&snic->snic_lock, gflags);

	if (snic->remove_wait)
		complete(snic->remove_wait);

	spin_unlock_irqrestore(io_lock, flags);
	atomic64_inc(&snic->s_stats.reset.hba_reset_cmpl);

	ret = 0;
	/* Rediscovery is for SAN */
	if (snic->config.xpt_type == SNIC_DAS)
			return ret;

	SNIC_SCSI_DBG(snic->shost, "reset_cmpl: Queuing discovery work.\n");
	queue_work(snic_glob->event_q, &snic->disc_work);

	return ret;
}

static void
snic_msg_ack_handler(struct snic *snic, struct snic_fw_req *fwreq)
{
	SNIC_HOST_INFO(snic->shost, "Message Ack Received.\n");

	SNIC_ASSERT_NOT_IMPL(1);
}

static void
snic_aen_handler(struct snic *snic, struct snic_fw_req *fwreq)
{
	u8 typ, hdr_stat;
	u32 cmnd_id, hid;
	ulong ctx;
	struct snic_async_evnotify *aen = &fwreq->u.async_ev;
	u32 event_id = 0;

	snic_io_hdr_dec(&fwreq->hdr, &typ, &hdr_stat, &cmnd_id, &hid, &ctx);
	SNIC_SCSI_DBG(snic->shost,
		      "aen: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x, ctx = %lx\n",
		      typ, hdr_stat, cmnd_id, hid, ctx);

	event_id = le32_to_cpu(aen->ev_id);

	switch (event_id) {
	case SNIC_EV_TGT_OFFLINE:
		SNIC_HOST_INFO(snic->shost, "aen:TGT_OFFLINE Event Recvd.\n");
		break;

	case SNIC_EV_TGT_ONLINE:
		SNIC_HOST_INFO(snic->shost, "aen:TGT_ONLINE Event Recvd.\n");
		break;

	case SNIC_EV_LUN_OFFLINE:
		SNIC_HOST_INFO(snic->shost, "aen:LUN_OFFLINE Event Recvd.\n");
		break;

	case SNIC_EV_LUN_ONLINE:
		SNIC_HOST_INFO(snic->shost, "aen:LUN_ONLINE Event Recvd.\n");
		break;

	case SNIC_EV_CONF_CHG:
		SNIC_HOST_INFO(snic->shost, "aen:Config Change Event Recvd.\n");
		break;

	case SNIC_EV_TGT_ADDED:
		SNIC_HOST_INFO(snic->shost, "aen:TGT_ADD Event Recvd.\n");
		break;

	case SNIC_EV_TGT_DELTD:
		SNIC_HOST_INFO(snic->shost, "aen:TGT_DEL Event Recvd.\n");
		break;

	case SNIC_EV_LUN_ADDED:
		SNIC_HOST_INFO(snic->shost, "aen:LUN_ADD Event Recvd.\n");
		break;

	case SNIC_EV_LUN_DELTD:
		SNIC_HOST_INFO(snic->shost, "aen:LUN_DEL Event Recvd.\n");
		break;

	case SNIC_EV_DISC_CMPL:
		SNIC_HOST_INFO(snic->shost, "aen:DISC_CMPL Event Recvd.\n");
		break;

	default:
		SNIC_HOST_INFO(snic->shost, "aen:Unknown Event Recvd.\n");
		SNIC_BUG_ON(1);
		break;
	}

	SNIC_ASSERT_NOT_IMPL(1);
} /* end of snic_aen_handler */

/*
 * snic_io_cmpl_handler
 * Routine to process CQ entries(IO Completions) posted by fw.
 */
static int
snic_io_cmpl_handler(struct vnic_dev *vdev,
		     unsigned int cq_idx,
		     struct snic_fw_req *fwreq)
{
	struct snic *snic = svnic_dev_priv(vdev);
	u64 start = jiffies, cmpl_time;

	snic_print_desc(__func__, (char *)fwreq, sizeof(*fwreq));

	/* Update FW Stats */
	if ((fwreq->hdr.type >= SNIC_RSP_REPORT_TGTS_CMPL) &&
		(fwreq->hdr.type <= SNIC_RSP_BOOT_LUNS_CMPL))
		atomic64_dec(&snic->s_stats.fw.actv_reqs);

	SNIC_BUG_ON((fwreq->hdr.type > SNIC_RSP_BOOT_LUNS_CMPL) &&
		    (fwreq->hdr.type < SNIC_MSG_ASYNC_EVNOTIFY));

	/* Check for snic subsys errors */
	switch (fwreq->hdr.status) {
	case SNIC_STAT_NOT_READY:	/* XPT yet to initialize */
		SNIC_HOST_ERR(snic->shost,
			      "sNIC SubSystem is NOT Ready.\n");
		break;

	case SNIC_STAT_FATAL_ERROR:	/* XPT Error */
		SNIC_HOST_ERR(snic->shost,
			      "sNIC SubSystem in Unrecoverable State.\n");
		break;
	}

	switch (fwreq->hdr.type) {
	case SNIC_RSP_EXCH_VER_CMPL:
		snic_io_exch_ver_cmpl_handler(snic, fwreq);
		break;

	case SNIC_RSP_REPORT_TGTS_CMPL:
		snic_report_tgt_cmpl_handler(snic, fwreq);
		break;

	case SNIC_RSP_ICMND_CMPL:
		snic_icmnd_cmpl_handler(snic, fwreq);
		break;

	case SNIC_RSP_ITMF_CMPL:
		snic_itmf_cmpl_handler(snic, fwreq);
		break;

	case SNIC_RSP_HBA_RESET_CMPL:
		snic_hba_reset_cmpl_handler(snic, fwreq);
		break;

	case SNIC_MSG_ACK:
		snic_msg_ack_handler(snic, fwreq);
		break;

	case SNIC_MSG_ASYNC_EVNOTIFY:
		snic_aen_handler(snic, fwreq);
		break;

	default:
		SNIC_BUG_ON(1);
		SNIC_SCSI_DBG(snic->shost,
			      "Unknown Firmware completion request type %d\n",
			      fwreq->hdr.type);
		break;
	}

	/* Update Stats */
	cmpl_time = jiffies - start;
	if (cmpl_time > atomic64_read(&snic->s_stats.io.max_cmpl_time))
		atomic64_set(&snic->s_stats.io.max_cmpl_time, cmpl_time);

	return 0;
} /* end of snic_io_cmpl_handler */

/*
 * snic_fwcq_cmpl_handler
 * Routine to process fwCQ
 * This CQ is independent, and not associated with wq/rq/wq_copy queues
 */
int
snic_fwcq_cmpl_handler(struct snic *snic, int io_cmpl_work)
{
	unsigned int num_ent = 0;	/* number cq entries processed */
	unsigned int cq_idx;
	unsigned int nent_per_cq;
	struct snic_misc_stats *misc_stats = &snic->s_stats.misc;

	for (cq_idx = snic->wq_count; cq_idx < snic->cq_count; cq_idx++) {
		nent_per_cq = vnic_cq_fw_service(&snic->cq[cq_idx],
						 snic_io_cmpl_handler,
						 io_cmpl_work);
		num_ent += nent_per_cq;

		if (nent_per_cq > atomic64_read(&misc_stats->max_cq_ents))
			atomic64_set(&misc_stats->max_cq_ents, nent_per_cq);
	}

	return num_ent;
} /* end of snic_fwcq_cmpl_handler */

/*
 * snic_queue_itmf_req: Common API to queue Task Management requests.
 * Use rqi->tm_tag for passing special tags.
 * @req_id : aborted request's tag, -1 for lun reset.
 */
static int
snic_queue_itmf_req(struct snic *snic,
		    struct snic_host_req *tmreq,
		    struct scsi_cmnd *sc,
		    u32 tmf,
		    u32 req_id)
{
	struct snic_req_info *rqi = req_to_rqi(tmreq);
	struct scsi_lun lun;
	int tm_tag = snic_cmd_tag(sc) | rqi->tm_tag;
	int ret = 0;

	SNIC_BUG_ON(!rqi);
	SNIC_BUG_ON(!rqi->tm_tag);

	/* fill in lun info */
	int_to_scsilun(sc->device->lun, &lun);

	/* Initialize snic_host_req: itmf */
	snic_itmf_init(tmreq,
		       tm_tag,
		       snic->config.hid,
		       (ulong) rqi,
		       0 /* flags */,
		       req_id, /* Command to be aborted. */
		       rqi->tgt_id,
		       lun.scsi_lun,
		       tmf);

	/*
	 * In case of multiple aborts on same cmd,
	 * use try_wait_for_completion and completion_done() to check
	 * whether it queues aborts even after completion of abort issued
	 * prior.SNIC_BUG_ON(completion_done(&rqi->done));
	 */

	ret = snic_queue_wq_desc(snic, tmreq, sizeof(*tmreq));
	if (ret)
		SNIC_HOST_ERR(snic->shost,
			      "qitmf:Queuing ITMF(%d) Req sc %p, rqi %p, req_id %d tag %d Failed, ret = %d\n",
			      tmf, sc, rqi, req_id, snic_cmd_tag(sc), ret);
	else
		SNIC_SCSI_DBG(snic->shost,
			      "qitmf:Queuing ITMF(%d) Req sc %p, rqi %p, req_id %d, tag %d (req_id)- Success.",
			      tmf, sc, rqi, req_id, snic_cmd_tag(sc));

	return ret;
} /* end of snic_queue_itmf_req */

static int
snic_issue_tm_req(struct snic *snic,
		    struct snic_req_info *rqi,
		    struct scsi_cmnd *sc,
		    int tmf)
{
	struct snic_host_req *tmreq = NULL;
	int req_id = 0, tag = snic_cmd_tag(sc);
	int ret = 0;

	if (snic_get_state(snic) == SNIC_FWRESET)
		return -EBUSY;

	atomic_inc(&snic->ios_inflight);

	SNIC_SCSI_DBG(snic->shost,
		      "issu_tmreq: Task mgmt req %d. rqi %p w/ tag %x\n",
		      tmf, rqi, tag);


	if (tmf == SNIC_ITMF_LUN_RESET) {
		tmreq = snic_dr_req_init(snic, rqi);
		req_id = SCSI_NO_TAG;
	} else {
		tmreq = snic_abort_req_init(snic, rqi);
		req_id = tag;
	}

	if (!tmreq) {
		ret = -ENOMEM;

		goto tmreq_err;
	}

	ret = snic_queue_itmf_req(snic, tmreq, sc, tmf, req_id);

tmreq_err:
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "issu_tmreq: Queueing ITMF(%d) Req, sc %p rqi %p req_id %d tag %x fails err = %d\n",
			      tmf, sc, rqi, req_id, tag, ret);
	} else {
		SNIC_SCSI_DBG(snic->shost,
			      "issu_tmreq: Queueing ITMF(%d) Req, sc %p, rqi %p, req_id %d tag %x - Success.\n",
			      tmf, sc, rqi, req_id, tag);
	}

	atomic_dec(&snic->ios_inflight);

	return ret;
}

/*
 * snic_queue_abort_req : Queues abort req to WQ
 */
static int
snic_queue_abort_req(struct snic *snic,
		     struct snic_req_info *rqi,
		     struct scsi_cmnd *sc,
		     int tmf)
{
	SNIC_SCSI_DBG(snic->shost, "q_abtreq: sc %p, rqi %p, tag %x, tmf %d\n",
		      sc, rqi, snic_cmd_tag(sc), tmf);

	/* Add special tag for abort */
	rqi->tm_tag |= SNIC_TAG_ABORT;

	return snic_issue_tm_req(snic, rqi, sc, tmf);
}

/*
 * snic_abort_finish : called by snic_abort_cmd on queuing abort successfully.
 */
static int
snic_abort_finish(struct snic *snic, struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	int ret = 0, tag = snic_cmd_tag(sc);

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);
	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (!rqi) {
		atomic64_inc(&snic->s_stats.io.req_null);
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_TERM_REQ_NULL;

		SNIC_SCSI_DBG(snic->shost,
			      "abt_fini:req info is null tag 0x%x, sc 0x%p flags 0x%llx\n",
			      tag, sc, CMD_FLAGS(sc));
		ret = FAILED;

		goto abort_fail;
	}

	rqi->abts_done = NULL;

	ret = FAILED;

	/* Check the abort status. */
	switch (CMD_ABTS_STATUS(sc)) {
	case SNIC_INVALID_CODE:
		/* Firmware didn't complete abort req, timedout */
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_TIMEDOUT;
		atomic64_inc(&snic->s_stats.abts.drv_tmo);
		SNIC_SCSI_DBG(snic->shost,
			      "abt_fini:sc %p Tag %x Driver Timeout.flags 0x%llx\n",
			      sc, snic_cmd_tag(sc), CMD_FLAGS(sc));
		/* do not release snic request in timedout case */
		rqi = NULL;

		goto abort_fail;

	case SNIC_STAT_IO_SUCCESS:
	case SNIC_STAT_IO_NOT_FOUND:
		ret = SUCCESS;
		/*
		 * If abort path doesn't call scsi_done(),
		 * the # IO timeouts == 2, will cause the LUN offline.
		 * Call scsi_done to complete the IO.
		 */
		sc->result = (DID_ERROR << 16);
		scsi_done(sc);
		break;

	default:
		/* Firmware completed abort with error */
		ret = FAILED;
		rqi = NULL;
		break;
	}

	CMD_SP(sc) = NULL;
	SNIC_HOST_INFO(snic->shost,
		       "abt_fini: Tag %x, Cmpl Status %s flags 0x%llx\n",
		       tag, snic_io_status_to_str(CMD_ABTS_STATUS(sc)),
		       CMD_FLAGS(sc));

abort_fail:
	spin_unlock_irqrestore(io_lock, flags);
	if (rqi)
		snic_release_req_buf(snic, rqi, sc);

	return ret;
} /* end of snic_abort_finish */

/*
 * snic_send_abort_and_wait : Issues Abort, and Waits
 */
static int
snic_send_abort_and_wait(struct snic *snic, struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	enum snic_ioreq_state sv_state;
	struct snic_tgt *tgt = NULL;
	spinlock_t *io_lock = NULL;
	DECLARE_COMPLETION_ONSTACK(tm_done);
	unsigned long flags;
	int ret = 0, tmf = 0, tag = snic_cmd_tag(sc);

	tgt = starget_to_tgt(scsi_target(sc->device));
	if ((snic_tgt_chkready(tgt) != 0) && (tgt->tdata.typ == SNIC_TGT_SAN))
		tmf = SNIC_ITMF_ABTS_TASK_TERM;
	else
		tmf = SNIC_ITMF_ABTS_TASK;

	/* stats */

	io_lock = snic_io_lock_hash(snic, sc);

	/*
	 * Avoid a race between SCSI issuing the abort and the device
	 * completing the command.
	 *
	 * If the command is already completed by fw_cmpl code,
	 * we just return SUCCESS from here. This means that the abort
	 * succeeded. In the SCSI ML, since the timeout for command has
	 * happend, the completion wont actually complete the command
	 * and it will be considered as an aborted command
	 *
	 * The CMD_SP will not be cleared except while holding io_lock
	 */
	spin_lock_irqsave(io_lock, flags);
	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (!rqi) {
		spin_unlock_irqrestore(io_lock, flags);

		SNIC_HOST_ERR(snic->shost,
			      "abt_cmd: rqi is null. Tag %d flags 0x%llx\n",
			      tag, CMD_FLAGS(sc));

		ret = SUCCESS;

		goto send_abts_end;
	}

	rqi->abts_done = &tm_done;
	if (CMD_STATE(sc) == SNIC_IOREQ_ABTS_PENDING) {
		spin_unlock_irqrestore(io_lock, flags);

		ret = 0;
		goto abts_pending;
	}
	SNIC_BUG_ON(!rqi->abts_done);

	/* Save Command State, should be restored on failed to Queue. */
	sv_state = CMD_STATE(sc);

	/*
	 * Command is still pending, need to abort it
	 * If the fw completes the command after this point,
	 * the completion won't be done till mid-layer, since abot
	 * has already started.
	 */
	CMD_STATE(sc) = SNIC_IOREQ_ABTS_PENDING;
	CMD_ABTS_STATUS(sc) = SNIC_INVALID_CODE;

	SNIC_SCSI_DBG(snic->shost, "send_abt_cmd: TAG 0x%x\n", tag);

	spin_unlock_irqrestore(io_lock, flags);

	/* Now Queue the abort command to firmware */
	ret = snic_queue_abort_req(snic, rqi, sc, tmf);
	if (ret) {
		atomic64_inc(&snic->s_stats.abts.q_fail);
		SNIC_HOST_ERR(snic->shost,
			      "send_abt_cmd: IO w/ Tag 0x%x fail w/ err %d flags 0x%llx\n",
			      tag, ret, CMD_FLAGS(sc));

		spin_lock_irqsave(io_lock, flags);
		/* Restore Command's previous state */
		CMD_STATE(sc) = sv_state;
		rqi = (struct snic_req_info *) CMD_SP(sc);
		if (rqi)
			rqi->abts_done = NULL;
		spin_unlock_irqrestore(io_lock, flags);
		ret = FAILED;

		goto send_abts_end;
	}

	spin_lock_irqsave(io_lock, flags);
	if (tmf == SNIC_ITMF_ABTS_TASK) {
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_ISSUED;
		atomic64_inc(&snic->s_stats.abts.num);
	} else {
		/* term stats */
		CMD_FLAGS(sc) |= SNIC_IO_TERM_ISSUED;
	}
	spin_unlock_irqrestore(io_lock, flags);

	SNIC_SCSI_DBG(snic->shost,
		      "send_abt_cmd: sc %p Tag %x flags 0x%llx\n",
		      sc, tag, CMD_FLAGS(sc));


	ret = 0;

abts_pending:
	/*
	 * Queued an abort IO, wait for its completion.
	 * Once the fw completes the abort command, it will
	 * wakeup this thread.
	 */
	wait_for_completion_timeout(&tm_done, SNIC_ABTS_TIMEOUT);

send_abts_end:
	return ret;
} /* end of snic_send_abort_and_wait */

/*
 * This function is exported to SCSI for sending abort cmnds.
 * A SCSI IO is represent by snic_ioreq in the driver.
 * The snic_ioreq is linked to the SCSI Cmd, thus a link with the ULP'S IO
 */
int
snic_abort_cmd(struct scsi_cmnd *sc)
{
	struct snic *snic = shost_priv(sc->device->host);
	int ret = SUCCESS, tag = snic_cmd_tag(sc);
	u32 start_time = jiffies;

	SNIC_SCSI_DBG(snic->shost, "abt_cmd:sc %p :0x%x :req = %p :tag = %d\n",
		       sc, sc->cmnd[0], scsi_cmd_to_rq(sc), tag);

	if (unlikely(snic_get_state(snic) != SNIC_ONLINE)) {
		SNIC_HOST_ERR(snic->shost,
			      "abt_cmd: tag %x Parent Devs are not rdy\n",
			      tag);
		ret = FAST_IO_FAIL;

		goto abort_end;
	}


	ret = snic_send_abort_and_wait(snic, sc);
	if (ret)
		goto abort_end;

	ret = snic_abort_finish(snic, sc);

abort_end:
	SNIC_TRC(snic->shost->host_no, tag, (ulong) sc,
		 jiffies_to_msecs(jiffies - start_time), 0,
		 SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));

	SNIC_SCSI_DBG(snic->shost,
		      "abts: Abort Req Status = %s\n",
		      (ret == SUCCESS) ? "SUCCESS" :
		       ((ret == FAST_IO_FAIL) ? "FAST_IO_FAIL" : "FAILED"));

	return ret;
}



static int
snic_is_abts_pending(struct snic *snic, struct scsi_cmnd *lr_sc)
{
	struct snic_req_info *rqi = NULL;
	struct scsi_cmnd *sc = NULL;
	struct scsi_device *lr_sdev = NULL;
	spinlock_t *io_lock = NULL;
	u32 tag;
	unsigned long flags;

	if (lr_sc)
		lr_sdev = lr_sc->device;

	/* walk through the tag map, an dcheck if IOs are still pending in fw*/
	for (tag = 0; tag < snic->max_tag_id; tag++) {
		io_lock = snic_io_lock_tag(snic, tag);

		spin_lock_irqsave(io_lock, flags);
		sc = scsi_host_find_tag(snic->shost, tag);

		if (!sc || (lr_sc && (sc->device != lr_sdev || sc == lr_sc))) {
			spin_unlock_irqrestore(io_lock, flags);

			continue;
		}

		rqi = (struct snic_req_info *) CMD_SP(sc);
		if (!rqi) {
			spin_unlock_irqrestore(io_lock, flags);

			continue;
		}

		/*
		 * Found IO that is still pending w/ firmware and belongs to
		 * the LUN that is under reset, if lr_sc != NULL
		 */
		SNIC_SCSI_DBG(snic->shost, "Found IO in %s on LUN\n",
			      snic_ioreq_state_to_str(CMD_STATE(sc)));

		if (CMD_STATE(sc) == SNIC_IOREQ_ABTS_PENDING) {
			spin_unlock_irqrestore(io_lock, flags);

			return 1;
		}

		spin_unlock_irqrestore(io_lock, flags);
	}

	return 0;
} /* end of snic_is_abts_pending */

static int
snic_dr_clean_single_req(struct snic *snic,
			 u32 tag,
			 struct scsi_device *lr_sdev)
{
	struct snic_req_info *rqi = NULL;
	struct snic_tgt *tgt = NULL;
	struct scsi_cmnd *sc = NULL;
	spinlock_t *io_lock = NULL;
	u32 sv_state = 0, tmf = 0;
	DECLARE_COMPLETION_ONSTACK(tm_done);
	unsigned long flags;
	int ret = 0;

	io_lock = snic_io_lock_tag(snic, tag);
	spin_lock_irqsave(io_lock, flags);
	sc = scsi_host_find_tag(snic->shost, tag);

	/* Ignore Cmd that don't belong to Lun Reset device */
	if (!sc || sc->device != lr_sdev)
		goto skip_clean;

	rqi = (struct snic_req_info *) CMD_SP(sc);

	if (!rqi)
		goto skip_clean;


	if (CMD_STATE(sc) == SNIC_IOREQ_ABTS_PENDING)
		goto skip_clean;


	if ((CMD_FLAGS(sc) & SNIC_DEVICE_RESET) &&
			(!(CMD_FLAGS(sc) & SNIC_DEV_RST_ISSUED))) {

		SNIC_SCSI_DBG(snic->shost,
			      "clean_single_req: devrst is not pending sc 0x%p\n",
			      sc);

		goto skip_clean;
	}

	SNIC_SCSI_DBG(snic->shost,
		"clean_single_req: Found IO in %s on lun\n",
		snic_ioreq_state_to_str(CMD_STATE(sc)));

	/* Save Command State */
	sv_state = CMD_STATE(sc);

	/*
	 * Any pending IO issued prior to reset is expected to be
	 * in abts pending state, if not we need to set SNIC_IOREQ_ABTS_PENDING
	 * to indicate the IO is abort pending.
	 * When IO is completed, the IO will be handed over and handled
	 * in this function.
	 */

	CMD_STATE(sc) = SNIC_IOREQ_ABTS_PENDING;
	SNIC_BUG_ON(rqi->abts_done);

	if (CMD_FLAGS(sc) & SNIC_DEVICE_RESET) {
		rqi->tm_tag = SNIC_TAG_DEV_RST;

		SNIC_SCSI_DBG(snic->shost,
			      "clean_single_req:devrst sc 0x%p\n", sc);
	}

	CMD_ABTS_STATUS(sc) = SNIC_INVALID_CODE;
	rqi->abts_done = &tm_done;
	spin_unlock_irqrestore(io_lock, flags);

	tgt = starget_to_tgt(scsi_target(sc->device));
	if ((snic_tgt_chkready(tgt) != 0) && (tgt->tdata.typ == SNIC_TGT_SAN))
		tmf = SNIC_ITMF_ABTS_TASK_TERM;
	else
		tmf = SNIC_ITMF_ABTS_TASK;

	/* Now queue the abort command to firmware */
	ret = snic_queue_abort_req(snic, rqi, sc, tmf);
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "clean_single_req_err:sc %p, tag %d abt failed. tm_tag %d flags 0x%llx\n",
			      sc, tag, rqi->tm_tag, CMD_FLAGS(sc));

		spin_lock_irqsave(io_lock, flags);
		rqi = (struct snic_req_info *) CMD_SP(sc);
		if (rqi)
			rqi->abts_done = NULL;

		/* Restore Command State */
		if (CMD_STATE(sc) == SNIC_IOREQ_ABTS_PENDING)
			CMD_STATE(sc) = sv_state;

		ret = 1;
		goto skip_clean;
	}

	spin_lock_irqsave(io_lock, flags);
	if (CMD_FLAGS(sc) & SNIC_DEVICE_RESET)
		CMD_FLAGS(sc) |= SNIC_DEV_RST_TERM_ISSUED;

	CMD_FLAGS(sc) |= SNIC_IO_INTERNAL_TERM_ISSUED;
	spin_unlock_irqrestore(io_lock, flags);

	wait_for_completion_timeout(&tm_done, SNIC_ABTS_TIMEOUT);

	/* Recheck cmd state to check if it now aborted. */
	spin_lock_irqsave(io_lock, flags);
	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (!rqi) {
		CMD_FLAGS(sc) |= SNIC_IO_ABTS_TERM_REQ_NULL;
		goto skip_clean;
	}
	rqi->abts_done = NULL;

	/* if abort is still pending w/ fw, fail */
	if (CMD_ABTS_STATUS(sc) == SNIC_INVALID_CODE) {
		SNIC_HOST_ERR(snic->shost,
			      "clean_single_req_err:sc %p tag %d abt still pending w/ fw, tm_tag %d flags 0x%llx\n",
			      sc, tag, rqi->tm_tag, CMD_FLAGS(sc));

		CMD_FLAGS(sc) |= SNIC_IO_ABTS_TERM_DONE;
		ret = 1;

		goto skip_clean;
	}

	CMD_STATE(sc) = SNIC_IOREQ_ABTS_COMPLETE;
	CMD_SP(sc) = NULL;
	spin_unlock_irqrestore(io_lock, flags);

	snic_release_req_buf(snic, rqi, sc);

	sc->result = (DID_ERROR << 16);
	scsi_done(sc);

	ret = 0;

	return ret;

skip_clean:
	spin_unlock_irqrestore(io_lock, flags);

	return ret;
} /* end of snic_dr_clean_single_req */

static int
snic_dr_clean_pending_req(struct snic *snic, struct scsi_cmnd *lr_sc)
{
	struct scsi_device *lr_sdev = lr_sc->device;
	u32 tag = 0;
	int ret;

	for (tag = 0; tag < snic->max_tag_id; tag++) {
		if (tag == snic_cmd_tag(lr_sc))
			continue;

		ret = snic_dr_clean_single_req(snic, tag, lr_sdev);
		if (ret) {
			SNIC_HOST_ERR(snic->shost, "clean_err:tag = %d\n", tag);
			goto clean_err;
		}
	}

	schedule_timeout(msecs_to_jiffies(100));

	/* Walk through all the cmds and check abts status. */
	if (snic_is_abts_pending(snic, lr_sc))
		goto clean_err;

	SNIC_SCSI_DBG(snic->shost, "clean_pending_req: Success.\n");

	return 0;

clean_err:
	SNIC_HOST_ERR(snic->shost,
		      "Failed to Clean Pending IOs on %s device.\n",
		      dev_name(&lr_sdev->sdev_gendev));

	return FAILED;

} /* end of snic_dr_clean_pending_req */

/*
 * snic_dr_finish : Called by snic_device_reset
 */
static int
snic_dr_finish(struct snic *snic, struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	int lr_res = 0;
	int ret = FAILED;

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);
	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (!rqi) {
		spin_unlock_irqrestore(io_lock, flags);
		SNIC_SCSI_DBG(snic->shost,
			      "dr_fini: rqi is null tag 0x%x sc 0x%p flags 0x%llx\n",
			      snic_cmd_tag(sc), sc, CMD_FLAGS(sc));

		ret = FAILED;
		goto dr_fini_end;
	}

	rqi->dr_done = NULL;

	lr_res = CMD_LR_STATUS(sc);

	switch (lr_res) {
	case SNIC_INVALID_CODE:
		/* stats */
		SNIC_SCSI_DBG(snic->shost,
			      "dr_fini: Tag %x Dev Reset Timedout. flags 0x%llx\n",
			      snic_cmd_tag(sc), CMD_FLAGS(sc));

		CMD_FLAGS(sc) |= SNIC_DEV_RST_TIMEDOUT;
		ret = FAILED;

		goto dr_failed;

	case SNIC_STAT_IO_SUCCESS:
		SNIC_SCSI_DBG(snic->shost,
			      "dr_fini: Tag %x Dev Reset cmpl\n",
			      snic_cmd_tag(sc));
		ret = 0;
		break;

	default:
		SNIC_HOST_ERR(snic->shost,
			      "dr_fini:Device Reset completed& failed.Tag = %x lr_status %s flags 0x%llx\n",
			      snic_cmd_tag(sc),
			      snic_io_status_to_str(lr_res), CMD_FLAGS(sc));
		ret = FAILED;
		goto dr_failed;
	}
	spin_unlock_irqrestore(io_lock, flags);

	/*
	 * Cleanup any IOs on this LUN that have still not completed.
	 * If any of these fail, then LUN Reset fails.
	 * Cleanup cleans all commands on this LUN except
	 * the lun reset command. If all cmds get cleaned, the LUN Reset
	 * succeeds.
	 */

	ret = snic_dr_clean_pending_req(snic, sc);
	if (ret) {
		spin_lock_irqsave(io_lock, flags);
		SNIC_SCSI_DBG(snic->shost,
			      "dr_fini: Device Reset Failed since could not abort all IOs. Tag = %x.\n",
			      snic_cmd_tag(sc));
		rqi = (struct snic_req_info *) CMD_SP(sc);

		goto dr_failed;
	} else {
		/* Cleanup LUN Reset Command */
		spin_lock_irqsave(io_lock, flags);
		rqi = (struct snic_req_info *) CMD_SP(sc);
		if (rqi)
			ret = SUCCESS; /* Completed Successfully */
		else
			ret = FAILED;
	}

dr_failed:
	lockdep_assert_held(io_lock);
	if (rqi)
		CMD_SP(sc) = NULL;
	spin_unlock_irqrestore(io_lock, flags);

	if (rqi)
		snic_release_req_buf(snic, rqi, sc);

dr_fini_end:
	return ret;
} /* end of snic_dr_finish */

static int
snic_queue_dr_req(struct snic *snic,
		  struct snic_req_info *rqi,
		  struct scsi_cmnd *sc)
{
	/* Add special tag for device reset */
	rqi->tm_tag |= SNIC_TAG_DEV_RST;

	return snic_issue_tm_req(snic, rqi, sc, SNIC_ITMF_LUN_RESET);
}

static int
snic_send_dr_and_wait(struct snic *snic, struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	enum snic_ioreq_state sv_state;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	DECLARE_COMPLETION_ONSTACK(tm_done);
	int ret = FAILED, tag = snic_cmd_tag(sc);

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);
	CMD_FLAGS(sc) |= SNIC_DEVICE_RESET;
	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (!rqi) {
		SNIC_HOST_ERR(snic->shost,
			      "send_dr: rqi is null, Tag 0x%x flags 0x%llx\n",
			      tag, CMD_FLAGS(sc));
		spin_unlock_irqrestore(io_lock, flags);

		ret = FAILED;
		goto send_dr_end;
	}

	/* Save Command state to restore in case Queuing failed. */
	sv_state = CMD_STATE(sc);

	CMD_STATE(sc) = SNIC_IOREQ_LR_PENDING;
	CMD_LR_STATUS(sc) = SNIC_INVALID_CODE;

	SNIC_SCSI_DBG(snic->shost, "dr: TAG = %x\n", tag);

	rqi->dr_done = &tm_done;
	SNIC_BUG_ON(!rqi->dr_done);

	spin_unlock_irqrestore(io_lock, flags);
	/*
	 * The Command state is changed to IOREQ_PENDING,
	 * in this case, if the command is completed, the icmnd_cmpl will
	 * mark the cmd as completed.
	 * This logic still makes LUN Reset is inevitable.
	 */

	ret = snic_queue_dr_req(snic, rqi, sc);
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "send_dr: IO w/ Tag 0x%x Failed err = %d. flags 0x%llx\n",
			      tag, ret, CMD_FLAGS(sc));

		spin_lock_irqsave(io_lock, flags);
		/* Restore State */
		CMD_STATE(sc) = sv_state;
		rqi = (struct snic_req_info *) CMD_SP(sc);
		if (rqi)
			rqi->dr_done = NULL;
		/* rqi is freed in caller. */
		spin_unlock_irqrestore(io_lock, flags);
		ret = FAILED;

		goto send_dr_end;
	}

	spin_lock_irqsave(io_lock, flags);
	CMD_FLAGS(sc) |= SNIC_DEV_RST_ISSUED;
	spin_unlock_irqrestore(io_lock, flags);

	ret = 0;

	wait_for_completion_timeout(&tm_done, SNIC_LUN_RESET_TIMEOUT);

send_dr_end:
	return ret;
}

/*
 * auxillary funciton to check lun reset op is supported or not
 * Not supported if returns 0
 */
static int
snic_dev_reset_supported(struct scsi_device *sdev)
{
	struct snic_tgt *tgt = starget_to_tgt(scsi_target(sdev));

	if (tgt->tdata.typ == SNIC_TGT_DAS)
		return 0;

	return 1;
}

static void
snic_unlink_and_release_req(struct snic *snic, struct scsi_cmnd *sc, int flag)
{
	struct snic_req_info *rqi = NULL;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	u32 start_time = jiffies;

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);
	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (rqi) {
		start_time = rqi->start_time;
		CMD_SP(sc) = NULL;
	}

	CMD_FLAGS(sc) |= flag;
	spin_unlock_irqrestore(io_lock, flags);

	if (rqi)
		snic_release_req_buf(snic, rqi, sc);

	SNIC_TRC(snic->shost->host_no, snic_cmd_tag(sc), (ulong) sc,
		 jiffies_to_msecs(jiffies - start_time), (ulong) rqi,
		 SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));
}

/*
 * SCSI Eh thread issues a LUN Reset when one or more commands on a LUN
 * fail to get aborted. It calls driver's eh_device_reset with a SCSI
 * command on the LUN.
 */
int
snic_device_reset(struct scsi_cmnd *sc)
{
	struct Scsi_Host *shost = sc->device->host;
	struct snic *snic = shost_priv(shost);
	struct snic_req_info *rqi = NULL;
	int tag = snic_cmd_tag(sc);
	int start_time = jiffies;
	int ret = FAILED;
	int dr_supp = 0;

	SNIC_SCSI_DBG(shost, "dev_reset:sc %p :0x%x :req = %p :tag = %d\n",
		      sc, sc->cmnd[0], scsi_cmd_to_rq(sc),
		      snic_cmd_tag(sc));
	dr_supp = snic_dev_reset_supported(sc->device);
	if (!dr_supp) {
		/* device reset op is not supported */
		SNIC_HOST_INFO(shost, "LUN Reset Op not supported.\n");
		snic_unlink_and_release_req(snic, sc, SNIC_DEV_RST_NOTSUP);

		goto dev_rst_end;
	}

	if (unlikely(snic_get_state(snic) != SNIC_ONLINE)) {
		snic_unlink_and_release_req(snic, sc, 0);
		SNIC_HOST_ERR(shost, "Devrst: Parent Devs are not online.\n");

		goto dev_rst_end;
	}

	/* There is no tag when lun reset is issue through ioctl. */
	if (unlikely(tag <= SNIC_NO_TAG)) {
		SNIC_HOST_INFO(snic->shost,
			       "Devrst: LUN Reset Recvd thru IOCTL.\n");

		rqi = snic_req_init(snic, 0);
		if (!rqi)
			goto dev_rst_end;

		memset(scsi_cmd_priv(sc), 0,
			sizeof(struct snic_internal_io_state));
		CMD_SP(sc) = (char *)rqi;
		CMD_FLAGS(sc) = SNIC_NO_FLAGS;

		/* Add special tag for dr coming from user spc */
		rqi->tm_tag = SNIC_TAG_IOCTL_DEV_RST;
		rqi->sc = sc;
	}

	ret = snic_send_dr_and_wait(snic, sc);
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "Devrst: IO w/ Tag %x Failed w/ err = %d\n",
			      tag, ret);

		snic_unlink_and_release_req(snic, sc, 0);

		goto dev_rst_end;
	}

	ret = snic_dr_finish(snic, sc);

dev_rst_end:
	SNIC_TRC(snic->shost->host_no, tag, (ulong) sc,
		 jiffies_to_msecs(jiffies - start_time),
		 0, SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));

	SNIC_SCSI_DBG(snic->shost,
		      "Devrst: Returning from Device Reset : %s\n",
		      (ret == SUCCESS) ? "SUCCESS" : "FAILED");

	return ret;
} /* end of snic_device_reset */

/*
 * SCSI Error handling calls driver's eh_host_reset if all prior
 * error handling levels return FAILED.
 *
 * Host Reset is the highest level of error recovery. If this fails, then
 * host is offlined by SCSI.
 */
/*
 * snic_issue_hba_reset : Queues FW Reset Request.
 */
static int
snic_issue_hba_reset(struct snic *snic, struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;
	struct snic_host_req *req = NULL;
	spinlock_t *io_lock = NULL;
	DECLARE_COMPLETION_ONSTACK(wait);
	unsigned long flags;
	int ret = -ENOMEM;

	rqi = snic_req_init(snic, 0);
	if (!rqi) {
		ret = -ENOMEM;

		goto hba_rst_end;
	}

	if (snic_cmd_tag(sc) == SCSI_NO_TAG) {
		memset(scsi_cmd_priv(sc), 0,
			sizeof(struct snic_internal_io_state));
		SNIC_HOST_INFO(snic->shost, "issu_hr:Host reset thru ioctl.\n");
		rqi->sc = sc;
	}

	req = rqi_to_req(rqi);

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);
	SNIC_BUG_ON(CMD_SP(sc) != NULL);
	CMD_STATE(sc) = SNIC_IOREQ_PENDING;
	CMD_SP(sc) = (char *) rqi;
	CMD_FLAGS(sc) |= SNIC_IO_INITIALIZED;
	snic->remove_wait = &wait;
	spin_unlock_irqrestore(io_lock, flags);

	/* Initialize Request */
	snic_io_hdr_enc(&req->hdr, SNIC_REQ_HBA_RESET, 0, snic_cmd_tag(sc),
			snic->config.hid, 0, (ulong) rqi);

	req->u.reset.flags = 0;

	ret = snic_queue_wq_desc(snic, req, sizeof(*req));
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "issu_hr:Queuing HBA Reset Failed. w err %d\n",
			      ret);

		goto hba_rst_err;
	}

	spin_lock_irqsave(io_lock, flags);
	CMD_FLAGS(sc) |= SNIC_HOST_RESET_ISSUED;
	spin_unlock_irqrestore(io_lock, flags);
	atomic64_inc(&snic->s_stats.reset.hba_resets);
	SNIC_HOST_INFO(snic->shost, "Queued HBA Reset Successfully.\n");

	wait_for_completion_timeout(snic->remove_wait,
				    SNIC_HOST_RESET_TIMEOUT);

	if (snic_get_state(snic) == SNIC_FWRESET) {
		SNIC_HOST_ERR(snic->shost, "reset_cmpl: Reset Timedout.\n");
		ret = -ETIMEDOUT;

		goto hba_rst_err;
	}

	spin_lock_irqsave(io_lock, flags);
	snic->remove_wait = NULL;
	rqi = (struct snic_req_info *) CMD_SP(sc);
	CMD_SP(sc) = NULL;
	spin_unlock_irqrestore(io_lock, flags);

	if (rqi)
		snic_req_free(snic, rqi);

	ret = 0;

	return ret;

hba_rst_err:
	spin_lock_irqsave(io_lock, flags);
	snic->remove_wait = NULL;
	rqi = (struct snic_req_info *) CMD_SP(sc);
	CMD_SP(sc) = NULL;
	spin_unlock_irqrestore(io_lock, flags);

	if (rqi)
		snic_req_free(snic, rqi);

hba_rst_end:
	SNIC_HOST_ERR(snic->shost,
		      "reset:HBA Reset Failed w/ err = %d.\n",
		      ret);

	return ret;
} /* end of snic_issue_hba_reset */

int
snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc)
{
	struct snic *snic = shost_priv(shost);
	enum snic_state sv_state;
	unsigned long flags;
	int ret = FAILED;

	/* Set snic state as SNIC_FWRESET*/
	sv_state = snic_get_state(snic);

	spin_lock_irqsave(&snic->snic_lock, flags);
	if (snic_get_state(snic) == SNIC_FWRESET) {
		spin_unlock_irqrestore(&snic->snic_lock, flags);
		SNIC_HOST_INFO(shost, "reset:prev reset is in progress\n");

		msleep(SNIC_HOST_RESET_TIMEOUT);
		ret = SUCCESS;

		goto reset_end;
	}

	snic_set_state(snic, SNIC_FWRESET);
	spin_unlock_irqrestore(&snic->snic_lock, flags);


	/* Wait for all the IOs that are entered in Qcmd */
	while (atomic_read(&snic->ios_inflight))
		schedule_timeout(msecs_to_jiffies(1));

	ret = snic_issue_hba_reset(snic, sc);
	if (ret) {
		SNIC_HOST_ERR(shost,
			      "reset:Host Reset Failed w/ err %d.\n",
			      ret);
		spin_lock_irqsave(&snic->snic_lock, flags);
		snic_set_state(snic, sv_state);
		spin_unlock_irqrestore(&snic->snic_lock, flags);
		atomic64_inc(&snic->s_stats.reset.hba_reset_fail);
		ret = FAILED;

		goto reset_end;
	}

	ret = SUCCESS;

reset_end:
	return ret;
} /* end of snic_reset */

/*
 * SCSI Error handling calls driver's eh_host_reset if all prior
 * error handling levels return FAILED.
 *
 * Host Reset is the highest level of error recovery. If this fails, then
 * host is offlined by SCSI.
 */
int
snic_host_reset(struct scsi_cmnd *sc)
{
	struct Scsi_Host *shost = sc->device->host;
	u32 start_time  = jiffies;
	int ret;

	SNIC_SCSI_DBG(shost,
		      "host reset:sc %p sc_cmd 0x%x req %p tag %d flags 0x%llx\n",
		      sc, sc->cmnd[0], scsi_cmd_to_rq(sc),
		      snic_cmd_tag(sc), CMD_FLAGS(sc));

	ret = snic_reset(shost, sc);

	SNIC_TRC(shost->host_no, snic_cmd_tag(sc), (ulong) sc,
		 jiffies_to_msecs(jiffies - start_time),
		 0, SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));

	return ret;
} /* end of snic_host_reset */

/*
 * snic_cmpl_pending_tmreq : Caller should hold io_lock
 */
static void
snic_cmpl_pending_tmreq(struct snic *snic, struct scsi_cmnd *sc)
{
	struct snic_req_info *rqi = NULL;

	SNIC_SCSI_DBG(snic->shost,
		      "Completing Pending TM Req sc %p, state %s flags 0x%llx\n",
		      sc, snic_io_status_to_str(CMD_STATE(sc)), CMD_FLAGS(sc));

	/*
	 * CASE : FW didn't post itmf completion due to PCIe Errors.
	 * Marking the abort status as Success to call scsi completion
	 * in snic_abort_finish()
	 */
	CMD_ABTS_STATUS(sc) = SNIC_STAT_IO_SUCCESS;

	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (!rqi)
		return;

	if (rqi->dr_done)
		complete(rqi->dr_done);
	else if (rqi->abts_done)
		complete(rqi->abts_done);
}

/*
 * snic_scsi_cleanup: Walks through tag map and releases the reqs
 */
static void
snic_scsi_cleanup(struct snic *snic, int ex_tag)
{
	struct snic_req_info *rqi = NULL;
	struct scsi_cmnd *sc = NULL;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	int tag;
	u64 st_time = 0;

	SNIC_SCSI_DBG(snic->shost, "sc_clean: scsi cleanup.\n");

	for (tag = 0; tag < snic->max_tag_id; tag++) {
		/* Skip ex_tag */
		if (tag == ex_tag)
			continue;

		io_lock = snic_io_lock_tag(snic, tag);
		spin_lock_irqsave(io_lock, flags);
		sc = scsi_host_find_tag(snic->shost, tag);
		if (!sc) {
			spin_unlock_irqrestore(io_lock, flags);

			continue;
		}

		if (unlikely(snic_tmreq_pending(sc))) {
			/*
			 * When FW Completes reset w/o sending completions
			 * for outstanding ios.
			 */
			snic_cmpl_pending_tmreq(snic, sc);
			spin_unlock_irqrestore(io_lock, flags);

			continue;
		}

		rqi = (struct snic_req_info *) CMD_SP(sc);
		if (!rqi) {
			spin_unlock_irqrestore(io_lock, flags);

			goto cleanup;
		}

		SNIC_SCSI_DBG(snic->shost,
			      "sc_clean: sc %p, rqi %p, tag %d flags 0x%llx\n",
			      sc, rqi, tag, CMD_FLAGS(sc));

		CMD_SP(sc) = NULL;
		CMD_FLAGS(sc) |= SNIC_SCSI_CLEANUP;
		spin_unlock_irqrestore(io_lock, flags);
		st_time = rqi->start_time;

		SNIC_HOST_INFO(snic->shost,
			       "sc_clean: Releasing rqi %p : flags 0x%llx\n",
			       rqi, CMD_FLAGS(sc));

		snic_release_req_buf(snic, rqi, sc);

cleanup:
		sc->result = DID_TRANSPORT_DISRUPTED << 16;
		SNIC_HOST_INFO(snic->shost,
			       "sc_clean: DID_TRANSPORT_DISRUPTED for sc %p, Tag %d flags 0x%llx rqi %p duration %u msecs\n",
			       sc, scsi_cmd_to_rq(sc)->tag, CMD_FLAGS(sc), rqi,
			       jiffies_to_msecs(jiffies - st_time));

		/* Update IO stats */
		snic_stats_update_io_cmpl(&snic->s_stats);

		SNIC_TRC(snic->shost->host_no, tag, (ulong) sc,
			 jiffies_to_msecs(jiffies - st_time), 0,
			 SNIC_TRC_CMD(sc),
			 SNIC_TRC_CMD_STATE_FLAGS(sc));

		scsi_done(sc);
	}
} /* end of snic_scsi_cleanup */

void
snic_shutdown_scsi_cleanup(struct snic *snic)
{
	SNIC_HOST_INFO(snic->shost, "Shutdown time SCSI Cleanup.\n");

	snic_scsi_cleanup(snic, SCSI_NO_TAG);
} /* end of snic_shutdown_scsi_cleanup */

/*
 * snic_internal_abort_io
 * called by : snic_tgt_scsi_abort_io
 */
static int
snic_internal_abort_io(struct snic *snic, struct scsi_cmnd *sc, int tmf)
{
	struct snic_req_info *rqi = NULL;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	u32 sv_state = 0;
	int ret = 0;

	io_lock = snic_io_lock_hash(snic, sc);
	spin_lock_irqsave(io_lock, flags);
	rqi = (struct snic_req_info *) CMD_SP(sc);
	if (!rqi)
		goto skip_internal_abts;

	if (CMD_STATE(sc) == SNIC_IOREQ_ABTS_PENDING)
		goto skip_internal_abts;

	if ((CMD_FLAGS(sc) & SNIC_DEVICE_RESET) &&
		(!(CMD_FLAGS(sc) & SNIC_DEV_RST_ISSUED))) {

		SNIC_SCSI_DBG(snic->shost,
			      "internal_abts: dev rst not pending sc 0x%p\n",
			      sc);

		goto skip_internal_abts;
	}


	if (!(CMD_FLAGS(sc) & SNIC_IO_ISSUED)) {
		SNIC_SCSI_DBG(snic->shost,
			"internal_abts: IO not yet issued sc 0x%p tag 0x%x flags 0x%llx state %d\n",
			sc, snic_cmd_tag(sc), CMD_FLAGS(sc), CMD_STATE(sc));

		goto skip_internal_abts;
	}

	sv_state = CMD_STATE(sc);
	CMD_STATE(sc) = SNIC_IOREQ_ABTS_PENDING;
	CMD_ABTS_STATUS(sc) = SNIC_INVALID_CODE;
	CMD_FLAGS(sc) |= SNIC_IO_INTERNAL_TERM_PENDING;

	if (CMD_FLAGS(sc) & SNIC_DEVICE_RESET) {
		/* stats */
		rqi->tm_tag = SNIC_TAG_DEV_RST;
		SNIC_SCSI_DBG(snic->shost, "internal_abts:dev rst sc %p\n", sc);
	}

	SNIC_SCSI_DBG(snic->shost, "internal_abts: Issuing abts tag %x\n",
		      snic_cmd_tag(sc));
	SNIC_BUG_ON(rqi->abts_done);
	spin_unlock_irqrestore(io_lock, flags);

	ret = snic_queue_abort_req(snic, rqi, sc, tmf);
	if (ret) {
		SNIC_HOST_ERR(snic->shost,
			      "internal_abts: Tag = %x , Failed w/ err = %d\n",
			      snic_cmd_tag(sc), ret);

		spin_lock_irqsave(io_lock, flags);

		if (CMD_STATE(sc) == SNIC_IOREQ_ABTS_PENDING)
			CMD_STATE(sc) = sv_state;

		goto skip_internal_abts;
	}

	spin_lock_irqsave(io_lock, flags);
	if (CMD_FLAGS(sc) & SNIC_DEVICE_RESET)
		CMD_FLAGS(sc) |= SNIC_DEV_RST_TERM_ISSUED;
	else
		CMD_FLAGS(sc) |= SNIC_IO_INTERNAL_TERM_ISSUED;

	ret = SUCCESS;

skip_internal_abts:
	lockdep_assert_held(io_lock);
	spin_unlock_irqrestore(io_lock, flags);

	return ret;
} /* end of snic_internal_abort_io */

/*
 * snic_tgt_scsi_abort_io : called by snic_tgt_del
 */
int
snic_tgt_scsi_abort_io(struct snic_tgt *tgt)
{
	struct snic *snic = NULL;
	struct scsi_cmnd *sc = NULL;
	struct snic_tgt *sc_tgt = NULL;
	spinlock_t *io_lock = NULL;
	unsigned long flags;
	int ret = 0, tag, abt_cnt = 0, tmf = 0;

	if (!tgt)
		return -1;

	snic = shost_priv(snic_tgt_to_shost(tgt));
	SNIC_SCSI_DBG(snic->shost, "tgt_abt_io: Cleaning Pending IOs.\n");

	if (tgt->tdata.typ == SNIC_TGT_DAS)
		tmf = SNIC_ITMF_ABTS_TASK;
	else
		tmf = SNIC_ITMF_ABTS_TASK_TERM;

	for (tag = 0; tag < snic->max_tag_id; tag++) {
		io_lock = snic_io_lock_tag(snic, tag);

		spin_lock_irqsave(io_lock, flags);
		sc = scsi_host_find_tag(snic->shost, tag);
		if (!sc) {
			spin_unlock_irqrestore(io_lock, flags);

			continue;
		}

		sc_tgt = starget_to_tgt(scsi_target(sc->device));
		if (sc_tgt != tgt) {
			spin_unlock_irqrestore(io_lock, flags);

			continue;
		}
		spin_unlock_irqrestore(io_lock, flags);

		ret = snic_internal_abort_io(snic, sc, tmf);
		if (ret < 0) {
			SNIC_HOST_ERR(snic->shost,
				      "tgt_abt_io: Tag %x, Failed w err = %d\n",
				      tag, ret);

			continue;
		}

		if (ret == SUCCESS)
			abt_cnt++;
	}

	SNIC_SCSI_DBG(snic->shost, "tgt_abt_io: abt_cnt = %d\n", abt_cnt);

	return 0;
} /* end of snic_tgt_scsi_abort_io */
