/*
 * This file is part of the Chelsio FCoE driver for Linux.
 *
 * Copyright (c) 2008-2012 Chelsio Communications, Inc. All rights reserved.
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <linux/device.h>
#include <linux/delay.h>
#include <linux/ctype.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/compiler.h>
#include <linux/export.h>
#include <linux/module.h>
#include <asm/unaligned.h>
#include <asm/page.h>
#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_transport_fc.h>

#include "csio_hw.h"
#include "csio_lnode.h"
#include "csio_rnode.h"
#include "csio_scsi.h"
#include "csio_init.h"

int csio_scsi_eqsize = 65536;
int csio_scsi_iqlen = 128;
int csio_scsi_ioreqs = 2048;
uint32_t csio_max_scan_tmo;
uint32_t csio_delta_scan_tmo = 5;
int csio_lun_qdepth = 32;

static int csio_ddp_descs = 128;

static int csio_do_abrt_cls(struct csio_hw *,
				      struct csio_ioreq *, bool);

static void csio_scsis_uninit(struct csio_ioreq *, enum csio_scsi_ev);
static void csio_scsis_io_active(struct csio_ioreq *, enum csio_scsi_ev);
static void csio_scsis_tm_active(struct csio_ioreq *, enum csio_scsi_ev);
static void csio_scsis_aborting(struct csio_ioreq *, enum csio_scsi_ev);
static void csio_scsis_closing(struct csio_ioreq *, enum csio_scsi_ev);
static void csio_scsis_shost_cmpl_await(struct csio_ioreq *, enum csio_scsi_ev);

/*
 * csio_scsi_match_io - Match an ioreq with the given SCSI level data.
 * @ioreq: The I/O request
 * @sld: Level information
 *
 * Should be called with lock held.
 *
 */
static bool
csio_scsi_match_io(struct csio_ioreq *ioreq, struct csio_scsi_level_data *sld)
{
	struct scsi_cmnd *scmnd = csio_scsi_cmnd(ioreq);

	switch (sld->level) {
	case CSIO_LEV_LUN:
		if (scmnd == NULL)
			return false;

		return ((ioreq->lnode == sld->lnode) &&
			(ioreq->rnode == sld->rnode) &&
			((uint64_t)scmnd->device->lun == sld->oslun));

	case CSIO_LEV_RNODE:
		return ((ioreq->lnode == sld->lnode) &&
				(ioreq->rnode == sld->rnode));
	case CSIO_LEV_LNODE:
		return (ioreq->lnode == sld->lnode);
	case CSIO_LEV_ALL:
		return true;
	default:
		return false;
	}
}

/*
 * csio_scsi_gather_active_ios - Gather active I/Os based on level
 * @scm: SCSI module
 * @sld: Level information
 * @dest: The queue where these I/Os have to be gathered.
 *
 * Should be called with lock held.
 */
static void
csio_scsi_gather_active_ios(struct csio_scsim *scm,
			    struct csio_scsi_level_data *sld,
			    struct list_head *dest)
{
	struct list_head *tmp, *next;

	if (list_empty(&scm->active_q))
		return;

	/* Just splice the entire active_q into dest */
	if (sld->level == CSIO_LEV_ALL) {
		list_splice_tail_init(&scm->active_q, dest);
		return;
	}

	list_for_each_safe(tmp, next, &scm->active_q) {
		if (csio_scsi_match_io((struct csio_ioreq *)tmp, sld)) {
			list_del_init(tmp);
			list_add_tail(tmp, dest);
		}
	}
}

static inline bool
csio_scsi_itnexus_loss_error(uint16_t error)
{
	switch (error) {
	case FW_ERR_LINK_DOWN:
	case FW_RDEV_NOT_READY:
	case FW_ERR_RDEV_LOST:
	case FW_ERR_RDEV_LOGO:
	case FW_ERR_RDEV_IMPL_LOGO:
		return true;
	}
	return false;
}

/*
 * csio_scsi_fcp_cmnd - Frame the SCSI FCP command paylod.
 * @req: IO req structure.
 * @addr: DMA location to place the payload.
 *
 * This routine is shared between FCP_WRITE, FCP_READ and FCP_CMD requests.
 */
static inline void
csio_scsi_fcp_cmnd(struct csio_ioreq *req, void *addr)
{
	struct fcp_cmnd *fcp_cmnd = (struct fcp_cmnd *)addr;
	struct scsi_cmnd *scmnd = csio_scsi_cmnd(req);

	/* Check for Task Management */
	if (likely(scmnd->SCp.Message == 0)) {
		int_to_scsilun(scmnd->device->lun, &fcp_cmnd->fc_lun);
		fcp_cmnd->fc_tm_flags = 0;
		fcp_cmnd->fc_cmdref = 0;

		memcpy(fcp_cmnd->fc_cdb, scmnd->cmnd, 16);
		fcp_cmnd->fc_pri_ta = FCP_PTA_SIMPLE;
		fcp_cmnd->fc_dl = cpu_to_be32(scsi_bufflen(scmnd));

		if (req->nsge)
			if (req->datadir == DMA_TO_DEVICE)
				fcp_cmnd->fc_flags = FCP_CFL_WRDATA;
			else
				fcp_cmnd->fc_flags = FCP_CFL_RDDATA;
		else
			fcp_cmnd->fc_flags = 0;
	} else {
		memset(fcp_cmnd, 0, sizeof(*fcp_cmnd));
		int_to_scsilun(scmnd->device->lun, &fcp_cmnd->fc_lun);
		fcp_cmnd->fc_tm_flags = (uint8_t)scmnd->SCp.Message;
	}
}

/*
 * csio_scsi_init_cmd_wr - Initialize the SCSI CMD WR.
 * @req: IO req structure.
 * @addr: DMA location to place the payload.
 * @size: Size of WR (including FW WR + immed data + rsp SG entry
 *
 * Wrapper for populating fw_scsi_cmd_wr.
 */
static inline void
csio_scsi_init_cmd_wr(struct csio_ioreq *req, void *addr, uint32_t size)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_rnode *rn = req->rnode;
	struct fw_scsi_cmd_wr *wr = (struct fw_scsi_cmd_wr *)addr;
	struct csio_dma_buf *dma_buf;
	uint8_t imm = csio_hw_to_scsim(hw)->proto_cmd_len;

	wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_CMD_WR) |
					  FW_SCSI_CMD_WR_IMMDLEN(imm));
	wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) |
					    FW_WR_LEN16_V(
						DIV_ROUND_UP(size, 16)));

	wr->cookie = (uintptr_t) req;
	wr->iqid = cpu_to_be16(csio_q_physiqid(hw, req->iq_idx));
	wr->tmo_val = (uint8_t) req->tmo;
	wr->r3 = 0;
	memset(&wr->r5, 0, 8);

	/* Get RSP DMA buffer */
	dma_buf = &req->dma_buf;

	/* Prepare RSP SGL */
	wr->rsp_dmalen = cpu_to_be32(dma_buf->len);
	wr->rsp_dmaaddr = cpu_to_be64(dma_buf->paddr);

	wr->r6 = 0;

	wr->u.fcoe.ctl_pri = 0;
	wr->u.fcoe.cp_en_class = 0;
	wr->u.fcoe.r4_lo[0] = 0;
	wr->u.fcoe.r4_lo[1] = 0;

	/* Frame a FCP command */
	csio_scsi_fcp_cmnd(req, (void *)((uintptr_t)addr +
				    sizeof(struct fw_scsi_cmd_wr)));
}

#define CSIO_SCSI_CMD_WR_SZ(_imm)					\
	(sizeof(struct fw_scsi_cmd_wr) +		/* WR size */	\
	 ALIGN((_imm), 16))				/* Immed data */

#define CSIO_SCSI_CMD_WR_SZ_16(_imm)					\
			(ALIGN(CSIO_SCSI_CMD_WR_SZ((_imm)), 16))

/*
 * csio_scsi_cmd - Create a SCSI CMD WR.
 * @req: IO req structure.
 *
 * Gets a WR slot in the ingress queue and initializes it with SCSI CMD WR.
 *
 */
static inline void
csio_scsi_cmd(struct csio_ioreq *req)
{
	struct csio_wr_pair wrp;
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);
	uint32_t size = CSIO_SCSI_CMD_WR_SZ_16(scsim->proto_cmd_len);

	req->drv_status = csio_wr_get(hw, req->eq_idx, size, &wrp);
	if (unlikely(req->drv_status != 0))
		return;

	if (wrp.size1 >= size) {
		/* Initialize WR in one shot */
		csio_scsi_init_cmd_wr(req, wrp.addr1, size);
	} else {
		uint8_t *tmpwr = csio_q_eq_wrap(hw, req->eq_idx);

		/*
		 * Make a temporary copy of the WR and write back
		 * the copy into the WR pair.
		 */
		csio_scsi_init_cmd_wr(req, (void *)tmpwr, size);
		memcpy(wrp.addr1, tmpwr, wrp.size1);
		memcpy(wrp.addr2, tmpwr + wrp.size1, size - wrp.size1);
	}
}

/*
 * csio_scsi_init_ulptx_dsgl - Fill in a ULP_TX_SC_DSGL
 * @hw: HW module
 * @req: IO request
 * @sgl: ULP TX SGL pointer.
 *
 */
static inline void
csio_scsi_init_ultptx_dsgl(struct csio_hw *hw, struct csio_ioreq *req,
			   struct ulptx_sgl *sgl)
{
	struct ulptx_sge_pair *sge_pair = NULL;
	struct scatterlist *sgel;
	uint32_t i = 0;
	uint32_t xfer_len;
	struct list_head *tmp;
	struct csio_dma_buf *dma_buf;
	struct scsi_cmnd *scmnd = csio_scsi_cmnd(req);

	sgl->cmd_nsge = htonl(ULPTX_CMD_V(ULP_TX_SC_DSGL) | ULPTX_MORE_F |
				     ULPTX_NSGE_V(req->nsge));
	/* Now add the data SGLs */
	if (likely(!req->dcopy)) {
		scsi_for_each_sg(scmnd, sgel, req->nsge, i) {
			if (i == 0) {
				sgl->addr0 = cpu_to_be64(sg_dma_address(sgel));
				sgl->len0 = cpu_to_be32(sg_dma_len(sgel));
				sge_pair = (struct ulptx_sge_pair *)(sgl + 1);
				continue;
			}
			if ((i - 1) & 0x1) {
				sge_pair->addr[1] = cpu_to_be64(
							sg_dma_address(sgel));
				sge_pair->len[1] = cpu_to_be32(
							sg_dma_len(sgel));
				sge_pair++;
			} else {
				sge_pair->addr[0] = cpu_to_be64(
							sg_dma_address(sgel));
				sge_pair->len[0] = cpu_to_be32(
							sg_dma_len(sgel));
			}
		}
	} else {
		/* Program sg elements with driver's DDP buffer */
		xfer_len = scsi_bufflen(scmnd);
		list_for_each(tmp, &req->gen_list) {
			dma_buf = (struct csio_dma_buf *)tmp;
			if (i == 0) {
				sgl->addr0 = cpu_to_be64(dma_buf->paddr);
				sgl->len0 = cpu_to_be32(
						min(xfer_len, dma_buf->len));
				sge_pair = (struct ulptx_sge_pair *)(sgl + 1);
			} else if ((i - 1) & 0x1) {
				sge_pair->addr[1] = cpu_to_be64(dma_buf->paddr);
				sge_pair->len[1] = cpu_to_be32(
						min(xfer_len, dma_buf->len));
				sge_pair++;
			} else {
				sge_pair->addr[0] = cpu_to_be64(dma_buf->paddr);
				sge_pair->len[0] = cpu_to_be32(
						min(xfer_len, dma_buf->len));
			}
			xfer_len -= min(xfer_len, dma_buf->len);
			i++;
		}
	}
}

/*
 * csio_scsi_init_read_wr - Initialize the READ SCSI WR.
 * @req: IO req structure.
 * @wrp: DMA location to place the payload.
 * @size: Size of WR (including FW WR + immed data + rsp SG entry + data SGL
 *
 * Wrapper for populating fw_scsi_read_wr.
 */
static inline void
csio_scsi_init_read_wr(struct csio_ioreq *req, void *wrp, uint32_t size)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_rnode *rn = req->rnode;
	struct fw_scsi_read_wr *wr = (struct fw_scsi_read_wr *)wrp;
	struct ulptx_sgl *sgl;
	struct csio_dma_buf *dma_buf;
	uint8_t imm = csio_hw_to_scsim(hw)->proto_cmd_len;
	struct scsi_cmnd *scmnd = csio_scsi_cmnd(req);

	wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_READ_WR) |
				     FW_SCSI_READ_WR_IMMDLEN(imm));
	wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) |
				       FW_WR_LEN16_V(DIV_ROUND_UP(size, 16)));
	wr->cookie = (uintptr_t)req;
	wr->iqid = cpu_to_be16(csio_q_physiqid(hw, req->iq_idx));
	wr->tmo_val = (uint8_t)(req->tmo);
	wr->use_xfer_cnt = 1;
	wr->xfer_cnt = cpu_to_be32(scsi_bufflen(scmnd));
	wr->ini_xfer_cnt = cpu_to_be32(scsi_bufflen(scmnd));
	/* Get RSP DMA buffer */
	dma_buf = &req->dma_buf;

	/* Prepare RSP SGL */
	wr->rsp_dmalen = cpu_to_be32(dma_buf->len);
	wr->rsp_dmaaddr = cpu_to_be64(dma_buf->paddr);

	wr->r4 = 0;

	wr->u.fcoe.ctl_pri = 0;
	wr->u.fcoe.cp_en_class = 0;
	wr->u.fcoe.r3_lo[0] = 0;
	wr->u.fcoe.r3_lo[1] = 0;
	csio_scsi_fcp_cmnd(req, (void *)((uintptr_t)wrp +
					sizeof(struct fw_scsi_read_wr)));

	/* Move WR pointer past command and immediate data */
	sgl = (struct ulptx_sgl *)((uintptr_t)wrp +
			      sizeof(struct fw_scsi_read_wr) + ALIGN(imm, 16));

	/* Fill in the DSGL */
	csio_scsi_init_ultptx_dsgl(hw, req, sgl);
}

/*
 * csio_scsi_init_write_wr - Initialize the WRITE SCSI WR.
 * @req: IO req structure.
 * @wrp: DMA location to place the payload.
 * @size: Size of WR (including FW WR + immed data + rsp SG entry + data SGL
 *
 * Wrapper for populating fw_scsi_write_wr.
 */
static inline void
csio_scsi_init_write_wr(struct csio_ioreq *req, void *wrp, uint32_t size)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_rnode *rn = req->rnode;
	struct fw_scsi_write_wr *wr = (struct fw_scsi_write_wr *)wrp;
	struct ulptx_sgl *sgl;
	struct csio_dma_buf *dma_buf;
	uint8_t imm = csio_hw_to_scsim(hw)->proto_cmd_len;
	struct scsi_cmnd *scmnd = csio_scsi_cmnd(req);

	wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_WRITE_WR) |
				     FW_SCSI_WRITE_WR_IMMDLEN(imm));
	wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) |
				       FW_WR_LEN16_V(DIV_ROUND_UP(size, 16)));
	wr->cookie = (uintptr_t)req;
	wr->iqid = cpu_to_be16(csio_q_physiqid(hw, req->iq_idx));
	wr->tmo_val = (uint8_t)(req->tmo);
	wr->use_xfer_cnt = 1;
	wr->xfer_cnt = cpu_to_be32(scsi_bufflen(scmnd));
	wr->ini_xfer_cnt = cpu_to_be32(scsi_bufflen(scmnd));
	/* Get RSP DMA buffer */
	dma_buf = &req->dma_buf;

	/* Prepare RSP SGL */
	wr->rsp_dmalen = cpu_to_be32(dma_buf->len);
	wr->rsp_dmaaddr = cpu_to_be64(dma_buf->paddr);

	wr->r4 = 0;

	wr->u.fcoe.ctl_pri = 0;
	wr->u.fcoe.cp_en_class = 0;
	wr->u.fcoe.r3_lo[0] = 0;
	wr->u.fcoe.r3_lo[1] = 0;
	csio_scsi_fcp_cmnd(req, (void *)((uintptr_t)wrp +
					sizeof(struct fw_scsi_write_wr)));

	/* Move WR pointer past command and immediate data */
	sgl = (struct ulptx_sgl *)((uintptr_t)wrp +
			      sizeof(struct fw_scsi_write_wr) + ALIGN(imm, 16));

	/* Fill in the DSGL */
	csio_scsi_init_ultptx_dsgl(hw, req, sgl);
}

/* Calculate WR size needed for fw_scsi_read_wr/fw_scsi_write_wr */
#define CSIO_SCSI_DATA_WRSZ(req, oper, sz, imm)				       \
do {									       \
	(sz) = sizeof(struct fw_scsi_##oper##_wr) +	/* WR size */          \
	       ALIGN((imm), 16) +			/* Immed data */       \
	       sizeof(struct ulptx_sgl);		/* ulptx_sgl */	       \
									       \
	if (unlikely((req)->nsge > 1))				               \
		(sz) += (sizeof(struct ulptx_sge_pair) *		       \
				(ALIGN(((req)->nsge - 1), 2) / 2));            \
							/* Data SGE */	       \
} while (0)

/*
 * csio_scsi_read - Create a SCSI READ WR.
 * @req: IO req structure.
 *
 * Gets a WR slot in the ingress queue and initializes it with
 * SCSI READ WR.
 *
 */
static inline void
csio_scsi_read(struct csio_ioreq *req)
{
	struct csio_wr_pair wrp;
	uint32_t size;
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);

	CSIO_SCSI_DATA_WRSZ(req, read, size, scsim->proto_cmd_len);
	size = ALIGN(size, 16);

	req->drv_status = csio_wr_get(hw, req->eq_idx, size, &wrp);
	if (likely(req->drv_status == 0)) {
		if (likely(wrp.size1 >= size)) {
			/* Initialize WR in one shot */
			csio_scsi_init_read_wr(req, wrp.addr1, size);
		} else {
			uint8_t *tmpwr = csio_q_eq_wrap(hw, req->eq_idx);
			/*
			 * Make a temporary copy of the WR and write back
			 * the copy into the WR pair.
			 */
			csio_scsi_init_read_wr(req, (void *)tmpwr, size);
			memcpy(wrp.addr1, tmpwr, wrp.size1);
			memcpy(wrp.addr2, tmpwr + wrp.size1, size - wrp.size1);
		}
	}
}

/*
 * csio_scsi_write - Create a SCSI WRITE WR.
 * @req: IO req structure.
 *
 * Gets a WR slot in the ingress queue and initializes it with
 * SCSI WRITE WR.
 *
 */
static inline void
csio_scsi_write(struct csio_ioreq *req)
{
	struct csio_wr_pair wrp;
	uint32_t size;
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);

	CSIO_SCSI_DATA_WRSZ(req, write, size, scsim->proto_cmd_len);
	size = ALIGN(size, 16);

	req->drv_status = csio_wr_get(hw, req->eq_idx, size, &wrp);
	if (likely(req->drv_status == 0)) {
		if (likely(wrp.size1 >= size)) {
			/* Initialize WR in one shot */
			csio_scsi_init_write_wr(req, wrp.addr1, size);
		} else {
			uint8_t *tmpwr = csio_q_eq_wrap(hw, req->eq_idx);
			/*
			 * Make a temporary copy of the WR and write back
			 * the copy into the WR pair.
			 */
			csio_scsi_init_write_wr(req, (void *)tmpwr, size);
			memcpy(wrp.addr1, tmpwr, wrp.size1);
			memcpy(wrp.addr2, tmpwr + wrp.size1, size - wrp.size1);
		}
	}
}

/*
 * csio_setup_ddp - Setup DDP buffers for Read request.
 * @req: IO req structure.
 *
 * Checks SGLs/Data buffers are virtually contiguous required for DDP.
 * If contiguous,driver posts SGLs in the WR otherwise post internal
 * buffers for such request for DDP.
 */
static inline void
csio_setup_ddp(struct csio_scsim *scsim, struct csio_ioreq *req)
{
#ifdef __CSIO_DEBUG__
	struct csio_hw *hw = req->lnode->hwp;
#endif
	struct scatterlist *sgel = NULL;
	struct scsi_cmnd *scmnd = csio_scsi_cmnd(req);
	uint64_t sg_addr = 0;
	uint32_t ddp_pagesz = 4096;
	uint32_t buf_off;
	struct csio_dma_buf *dma_buf = NULL;
	uint32_t alloc_len = 0;
	uint32_t xfer_len = 0;
	uint32_t sg_len = 0;
	uint32_t i;

	scsi_for_each_sg(scmnd, sgel, req->nsge, i) {
		sg_addr = sg_dma_address(sgel);
		sg_len	= sg_dma_len(sgel);

		buf_off = sg_addr & (ddp_pagesz - 1);

		/* Except 1st buffer,all buffer addr have to be Page aligned */
		if (i != 0 && buf_off) {
			csio_dbg(hw, "SGL addr not DDP aligned (%llx:%d)\n",
				 sg_addr, sg_len);
			goto unaligned;
		}

		/* Except last buffer,all buffer must end on page boundary */
		if ((i != (req->nsge - 1)) &&
			((buf_off + sg_len) & (ddp_pagesz - 1))) {
			csio_dbg(hw,
				 "SGL addr not ending on page boundary"
				 "(%llx:%d)\n", sg_addr, sg_len);
			goto unaligned;
		}
	}

	/* SGL's are virtually contiguous. HW will DDP to SGLs */
	req->dcopy = 0;
	csio_scsi_read(req);

	return;

unaligned:
	CSIO_INC_STATS(scsim, n_unaligned);
	/*
	 * For unaligned SGLs, driver will allocate internal DDP buffer.
	 * Once command is completed data from DDP buffer copied to SGLs
	 */
	req->dcopy = 1;

	/* Use gen_list to store the DDP buffers */
	INIT_LIST_HEAD(&req->gen_list);
	xfer_len = scsi_bufflen(scmnd);

	i = 0;
	/* Allocate ddp buffers for this request */
	while (alloc_len < xfer_len) {
		dma_buf = csio_get_scsi_ddp(scsim);
		if (dma_buf == NULL || i > scsim->max_sge) {
			req->drv_status = -EBUSY;
			break;
		}
		alloc_len += dma_buf->len;
		/* Added to IO req */
		list_add_tail(&dma_buf->list, &req->gen_list);
		i++;
	}

	if (!req->drv_status) {
		/* set number of ddp bufs used */
		req->nsge = i;
		csio_scsi_read(req);
		return;
	}

	 /* release dma descs */
	if (i > 0)
		csio_put_scsi_ddp_list(scsim, &req->gen_list, i);
}

/*
 * csio_scsi_init_abrt_cls_wr - Initialize an ABORT/CLOSE WR.
 * @req: IO req structure.
 * @addr: DMA location to place the payload.
 * @size: Size of WR
 * @abort: abort OR close
 *
 * Wrapper for populating fw_scsi_cmd_wr.
 */
static inline void
csio_scsi_init_abrt_cls_wr(struct csio_ioreq *req, void *addr, uint32_t size,
			   bool abort)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_rnode *rn = req->rnode;
	struct fw_scsi_abrt_cls_wr *wr = (struct fw_scsi_abrt_cls_wr *)addr;

	wr->op_immdlen = cpu_to_be32(FW_WR_OP_V(FW_SCSI_ABRT_CLS_WR));
	wr->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(rn->flowid) |
					    FW_WR_LEN16_V(
						DIV_ROUND_UP(size, 16)));

	wr->cookie = (uintptr_t) req;
	wr->iqid = cpu_to_be16(csio_q_physiqid(hw, req->iq_idx));
	wr->tmo_val = (uint8_t) req->tmo;
	/* 0 for CHK_ALL_IO tells FW to look up t_cookie */
	wr->sub_opcode_to_chk_all_io =
				(FW_SCSI_ABRT_CLS_WR_SUB_OPCODE(abort) |
				 FW_SCSI_ABRT_CLS_WR_CHK_ALL_IO(0));
	wr->r3[0] = 0;
	wr->r3[1] = 0;
	wr->r3[2] = 0;
	wr->r3[3] = 0;
	/* Since we re-use the same ioreq for abort as well */
	wr->t_cookie = (uintptr_t) req;
}

static inline void
csio_scsi_abrt_cls(struct csio_ioreq *req, bool abort)
{
	struct csio_wr_pair wrp;
	struct csio_hw *hw = req->lnode->hwp;
	uint32_t size = ALIGN(sizeof(struct fw_scsi_abrt_cls_wr), 16);

	req->drv_status = csio_wr_get(hw, req->eq_idx, size, &wrp);
	if (req->drv_status != 0)
		return;

	if (wrp.size1 >= size) {
		/* Initialize WR in one shot */
		csio_scsi_init_abrt_cls_wr(req, wrp.addr1, size, abort);
	} else {
		uint8_t *tmpwr = csio_q_eq_wrap(hw, req->eq_idx);
		/*
		 * Make a temporary copy of the WR and write back
		 * the copy into the WR pair.
		 */
		csio_scsi_init_abrt_cls_wr(req, (void *)tmpwr, size, abort);
		memcpy(wrp.addr1, tmpwr, wrp.size1);
		memcpy(wrp.addr2, tmpwr + wrp.size1, size - wrp.size1);
	}
}

/*****************************************************************************/
/* START: SCSI SM                                                            */
/*****************************************************************************/
static void
csio_scsis_uninit(struct csio_ioreq *req, enum csio_scsi_ev evt)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);

	switch (evt) {
	case CSIO_SCSIE_START_IO:

		if (req->nsge) {
			if (req->datadir == DMA_TO_DEVICE) {
				req->dcopy = 0;
				csio_scsi_write(req);
			} else
				csio_setup_ddp(scsim, req);
		} else {
			csio_scsi_cmd(req);
		}

		if (likely(req->drv_status == 0)) {
			/* change state and enqueue on active_q */
			csio_set_state(&req->sm, csio_scsis_io_active);
			list_add_tail(&req->sm.sm_list, &scsim->active_q);
			csio_wr_issue(hw, req->eq_idx, false);
			CSIO_INC_STATS(scsim, n_active);

			return;
		}
		break;

	case CSIO_SCSIE_START_TM:
		csio_scsi_cmd(req);
		if (req->drv_status == 0) {
			/*
			 * NOTE: We collect the affected I/Os prior to issuing
			 * LUN reset, and not after it. This is to prevent
			 * aborting I/Os that get issued after the LUN reset,
			 * but prior to LUN reset completion (in the event that
			 * the host stack has not blocked I/Os to a LUN that is
			 * being reset.
			 */
			csio_set_state(&req->sm, csio_scsis_tm_active);
			list_add_tail(&req->sm.sm_list, &scsim->active_q);
			csio_wr_issue(hw, req->eq_idx, false);
			CSIO_INC_STATS(scsim, n_tm_active);
		}
		return;

	case CSIO_SCSIE_ABORT:
	case CSIO_SCSIE_CLOSE:
		/*
		 * NOTE:
		 * We could get here due to  :
		 * - a window in the cleanup path of the SCSI module
		 *   (csio_scsi_abort_io()). Please see NOTE in this function.
		 * - a window in the time we tried to issue an abort/close
		 *   of a request to FW, and the FW completed the request
		 *   itself.
		 *   Print a message for now, and return INVAL either way.
		 */
		req->drv_status = -EINVAL;
		csio_warn(hw, "Trying to abort/close completed IO:%p!\n", req);
		break;

	default:
		csio_dbg(hw, "Unhandled event:%d sent to req:%p\n", evt, req);
		CSIO_DB_ASSERT(0);
	}
}

static void
csio_scsis_io_active(struct csio_ioreq *req, enum csio_scsi_ev evt)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scm = csio_hw_to_scsim(hw);
	struct csio_rnode *rn;

	switch (evt) {
	case CSIO_SCSIE_COMPLETED:
		CSIO_DEC_STATS(scm, n_active);
		list_del_init(&req->sm.sm_list);
		csio_set_state(&req->sm, csio_scsis_uninit);
		/*
		 * In MSIX mode, with multiple queues, the SCSI compeltions
		 * could reach us sooner than the FW events sent to indicate
		 * I-T nexus loss (link down, remote device logo etc). We
		 * dont want to be returning such I/Os to the upper layer
		 * immediately, since we wouldnt have reported the I-T nexus
		 * loss itself. This forces us to serialize such completions
		 * with the reporting of the I-T nexus loss. Therefore, we
		 * internally queue up such up such completions in the rnode.
		 * The reporting of I-T nexus loss to the upper layer is then
		 * followed by the returning of I/Os in this internal queue.
		 * Having another state alongwith another queue helps us take
		 * actions for events such as ABORT received while we are
		 * in this rnode queue.
		 */
		if (unlikely(req->wr_status != FW_SUCCESS)) {
			rn = req->rnode;
			/*
			 * FW says remote device is lost, but rnode
			 * doesnt reflect it.
			 */
			if (csio_scsi_itnexus_loss_error(req->wr_status) &&
						csio_is_rnode_ready(rn)) {
				csio_set_state(&req->sm,
						csio_scsis_shost_cmpl_await);
				list_add_tail(&req->sm.sm_list,
					      &rn->host_cmpl_q);
			}
		}

		break;

	case CSIO_SCSIE_ABORT:
		csio_scsi_abrt_cls(req, SCSI_ABORT);
		if (req->drv_status == 0) {
			csio_wr_issue(hw, req->eq_idx, false);
			csio_set_state(&req->sm, csio_scsis_aborting);
		}
		break;

	case CSIO_SCSIE_CLOSE:
		csio_scsi_abrt_cls(req, SCSI_CLOSE);
		if (req->drv_status == 0) {
			csio_wr_issue(hw, req->eq_idx, false);
			csio_set_state(&req->sm, csio_scsis_closing);
		}
		break;

	case CSIO_SCSIE_DRVCLEANUP:
		req->wr_status = FW_HOSTERROR;
		CSIO_DEC_STATS(scm, n_active);
		csio_set_state(&req->sm, csio_scsis_uninit);
		break;

	default:
		csio_dbg(hw, "Unhandled event:%d sent to req:%p\n", evt, req);
		CSIO_DB_ASSERT(0);
	}
}

static void
csio_scsis_tm_active(struct csio_ioreq *req, enum csio_scsi_ev evt)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scm = csio_hw_to_scsim(hw);

	switch (evt) {
	case CSIO_SCSIE_COMPLETED:
		CSIO_DEC_STATS(scm, n_tm_active);
		list_del_init(&req->sm.sm_list);
		csio_set_state(&req->sm, csio_scsis_uninit);

		break;

	case CSIO_SCSIE_ABORT:
		csio_scsi_abrt_cls(req, SCSI_ABORT);
		if (req->drv_status == 0) {
			csio_wr_issue(hw, req->eq_idx, false);
			csio_set_state(&req->sm, csio_scsis_aborting);
		}
		break;


	case CSIO_SCSIE_CLOSE:
		csio_scsi_abrt_cls(req, SCSI_CLOSE);
		if (req->drv_status == 0) {
			csio_wr_issue(hw, req->eq_idx, false);
			csio_set_state(&req->sm, csio_scsis_closing);
		}
		break;

	case CSIO_SCSIE_DRVCLEANUP:
		req->wr_status = FW_HOSTERROR;
		CSIO_DEC_STATS(scm, n_tm_active);
		csio_set_state(&req->sm, csio_scsis_uninit);
		break;

	default:
		csio_dbg(hw, "Unhandled event:%d sent to req:%p\n", evt, req);
		CSIO_DB_ASSERT(0);
	}
}

static void
csio_scsis_aborting(struct csio_ioreq *req, enum csio_scsi_ev evt)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scm = csio_hw_to_scsim(hw);

	switch (evt) {
	case CSIO_SCSIE_COMPLETED:
		csio_dbg(hw,
			 "ioreq %p recvd cmpltd (wr_status:%d) "
			 "in aborting st\n", req, req->wr_status);
		/*
		 * Use -ECANCELED to explicitly tell the ABORTED event that
		 * the original I/O was returned to driver by FW.
		 * We dont really care if the I/O was returned with success by
		 * FW (because the ABORT and completion of the I/O crossed each
		 * other), or any other return value. Once we are in aborting
		 * state, the success or failure of the I/O is unimportant to
		 * us.
		 */
		req->drv_status = -ECANCELED;
		break;

	case CSIO_SCSIE_ABORT:
		CSIO_INC_STATS(scm, n_abrt_dups);
		break;

	case CSIO_SCSIE_ABORTED:

		csio_dbg(hw, "abort of %p return status:0x%x drv_status:%x\n",
			 req, req->wr_status, req->drv_status);
		/*
		 * Check if original I/O WR completed before the Abort
		 * completion.
		 */
		if (req->drv_status != -ECANCELED) {
			csio_warn(hw,
				  "Abort completed before original I/O,"
				   " req:%p\n", req);
			CSIO_DB_ASSERT(0);
		}

		/*
		 * There are the following possible scenarios:
		 * 1. The abort completed successfully, FW returned FW_SUCCESS.
		 * 2. The completion of an I/O and the receipt of
		 *    abort for that I/O by the FW crossed each other.
		 *    The FW returned FW_EINVAL. The original I/O would have
		 *    returned with FW_SUCCESS or any other SCSI error.
		 * 3. The FW couldn't sent the abort out on the wire, as there
		 *    was an I-T nexus loss (link down, remote device logged
		 *    out etc). FW sent back an appropriate IT nexus loss status
		 *    for the abort.
		 * 4. FW sent an abort, but abort timed out (remote device
		 *    didnt respond). FW replied back with
		 *    FW_SCSI_ABORT_TIMEDOUT.
		 * 5. FW couldn't genuinely abort the request for some reason,
		 *    and sent us an error.
		 *
		 * The first 3 scenarios are treated as  succesful abort
		 * operations by the host, while the last 2 are failed attempts
		 * to abort. Manipulate the return value of the request
		 * appropriately, so that host can convey these results
		 * back to the upper layer.
		 */
		if ((req->wr_status == FW_SUCCESS) ||
		    (req->wr_status == FW_EINVAL) ||
		    csio_scsi_itnexus_loss_error(req->wr_status))
			req->wr_status = FW_SCSI_ABORT_REQUESTED;

		CSIO_DEC_STATS(scm, n_active);
		list_del_init(&req->sm.sm_list);
		csio_set_state(&req->sm, csio_scsis_uninit);
		break;

	case CSIO_SCSIE_DRVCLEANUP:
		req->wr_status = FW_HOSTERROR;
		CSIO_DEC_STATS(scm, n_active);
		csio_set_state(&req->sm, csio_scsis_uninit);
		break;

	case CSIO_SCSIE_CLOSE:
		/*
		 * We can receive this event from the module
		 * cleanup paths, if the FW forgot to reply to the ABORT WR
		 * and left this ioreq in this state. For now, just ignore
		 * the event. The CLOSE event is sent to this state, as
		 * the LINK may have already gone down.
		 */
		break;

	default:
		csio_dbg(hw, "Unhandled event:%d sent to req:%p\n", evt, req);
		CSIO_DB_ASSERT(0);
	}
}

static void
csio_scsis_closing(struct csio_ioreq *req, enum csio_scsi_ev evt)
{
	struct csio_hw *hw = req->lnode->hwp;
	struct csio_scsim *scm = csio_hw_to_scsim(hw);

	switch (evt) {
	case CSIO_SCSIE_COMPLETED:
		csio_dbg(hw,
			 "ioreq %p recvd cmpltd (wr_status:%d) "
			 "in closing st\n", req, req->wr_status);
		/*
		 * Use -ECANCELED to explicitly tell the CLOSED event that
		 * the original I/O was returned to driver by FW.
		 * We dont really care if the I/O was returned with success by
		 * FW (because the CLOSE and completion of the I/O crossed each
		 * other), or any other return value. Once we are in aborting
		 * state, the success or failure of the I/O is unimportant to
		 * us.
		 */
		req->drv_status = -ECANCELED;
		break;

	case CSIO_SCSIE_CLOSED:
		/*
		 * Check if original I/O WR completed before the Close
		 * completion.
		 */
		if (req->drv_status != -ECANCELED) {
			csio_fatal(hw,
				   "Close completed before original I/O,"
				   " req:%p\n", req);
			CSIO_DB_ASSERT(0);
		}

		/*
		 * Either close succeeded, or we issued close to FW at the
		 * same time FW compelted it to us. Either way, the I/O
		 * is closed.
		 */
		CSIO_DB_ASSERT((req->wr_status == FW_SUCCESS) ||
					(req->wr_status == FW_EINVAL));
		req->wr_status = FW_SCSI_CLOSE_REQUESTED;

		CSIO_DEC_STATS(scm, n_active);
		list_del_init(&req->sm.sm_list);
		csio_set_state(&req->sm, csio_scsis_uninit);
		break;

	case CSIO_SCSIE_CLOSE:
		break;

	case CSIO_SCSIE_DRVCLEANUP:
		req->wr_status = FW_HOSTERROR;
		CSIO_DEC_STATS(scm, n_active);
		csio_set_state(&req->sm, csio_scsis_uninit);
		break;

	default:
		csio_dbg(hw, "Unhandled event:%d sent to req:%p\n", evt, req);
		CSIO_DB_ASSERT(0);
	}
}

static void
csio_scsis_shost_cmpl_await(struct csio_ioreq *req, enum csio_scsi_ev evt)
{
	switch (evt) {
	case CSIO_SCSIE_ABORT:
	case CSIO_SCSIE_CLOSE:
		/*
		 * Just succeed the abort request, and hope that
		 * the remote device unregister path will cleanup
		 * this I/O to the upper layer within a sane
		 * amount of time.
		 */
		/*
		 * A close can come in during a LINK DOWN. The FW would have
		 * returned us the I/O back, but not the remote device lost
		 * FW event. In this interval, if the I/O times out at the upper
		 * layer, a close can come in. Take the same action as abort:
		 * return success, and hope that the remote device unregister
		 * path will cleanup this I/O. If the FW still doesnt send
		 * the msg, the close times out, and the upper layer resorts
		 * to the next level of error recovery.
		 */
		req->drv_status = 0;
		break;
	case CSIO_SCSIE_DRVCLEANUP:
		csio_set_state(&req->sm, csio_scsis_uninit);
		break;
	default:
		csio_dbg(req->lnode->hwp, "Unhandled event:%d sent to req:%p\n",
			 evt, req);
		CSIO_DB_ASSERT(0);
	}
}

/*
 * csio_scsi_cmpl_handler - WR completion handler for SCSI.
 * @hw: HW module.
 * @wr: The completed WR from the ingress queue.
 * @len: Length of the WR.
 * @flb: Freelist buffer array.
 * @priv: Private object
 * @scsiwr: Pointer to SCSI WR.
 *
 * This is the WR completion handler called per completion from the
 * ISR. It is called with lock held. It walks past the RSS and CPL message
 * header where the actual WR is present.
 * It then gets the status, WR handle (ioreq pointer) and the len of
 * the WR, based on WR opcode. Only on a non-good status is the entire
 * WR copied into the WR cache (ioreq->fw_wr).
 * The ioreq corresponding to the WR is returned to the caller.
 * NOTE: The SCSI queue doesnt allocate a freelist today, hence
 * no freelist buffer is expected.
 */
struct csio_ioreq *
csio_scsi_cmpl_handler(struct csio_hw *hw, void *wr, uint32_t len,
		     struct csio_fl_dma_buf *flb, void *priv, uint8_t **scsiwr)
{
	struct csio_ioreq *ioreq = NULL;
	struct cpl_fw6_msg *cpl;
	uint8_t *tempwr;
	uint8_t	status;
	struct csio_scsim *scm = csio_hw_to_scsim(hw);

	/* skip RSS header */
	cpl = (struct cpl_fw6_msg *)((uintptr_t)wr + sizeof(__be64));

	if (unlikely(cpl->opcode != CPL_FW6_MSG)) {
		csio_warn(hw, "Error: Invalid CPL msg %x recvd on SCSI q\n",
			  cpl->opcode);
		CSIO_INC_STATS(scm, n_inval_cplop);
		return NULL;
	}

	tempwr = (uint8_t *)(cpl->data);
	status = csio_wr_status(tempwr);
	*scsiwr = tempwr;

	if (likely((*tempwr == FW_SCSI_READ_WR) ||
			(*tempwr == FW_SCSI_WRITE_WR) ||
			(*tempwr == FW_SCSI_CMD_WR))) {
		ioreq = (struct csio_ioreq *)((uintptr_t)
				 (((struct fw_scsi_read_wr *)tempwr)->cookie));
		CSIO_DB_ASSERT(virt_addr_valid(ioreq));

		ioreq->wr_status = status;

		return ioreq;
	}

	if (*tempwr == FW_SCSI_ABRT_CLS_WR) {
		ioreq = (struct csio_ioreq *)((uintptr_t)
			 (((struct fw_scsi_abrt_cls_wr *)tempwr)->cookie));
		CSIO_DB_ASSERT(virt_addr_valid(ioreq));

		ioreq->wr_status = status;
		return ioreq;
	}

	csio_warn(hw, "WR with invalid opcode in SCSI IQ: %x\n", *tempwr);
	CSIO_INC_STATS(scm, n_inval_scsiop);
	return NULL;
}

/*
 * csio_scsi_cleanup_io_q - Cleanup the given queue.
 * @scm: SCSI module.
 * @q: Queue to be cleaned up.
 *
 * Called with lock held. Has to exit with lock held.
 */
void
csio_scsi_cleanup_io_q(struct csio_scsim *scm, struct list_head *q)
{
	struct csio_hw *hw = scm->hw;
	struct csio_ioreq *ioreq;
	struct list_head *tmp, *next;
	struct scsi_cmnd *scmnd;

	/* Call back the completion routines of the active_q */
	list_for_each_safe(tmp, next, q) {
		ioreq = (struct csio_ioreq *)tmp;
		csio_scsi_drvcleanup(ioreq);
		list_del_init(&ioreq->sm.sm_list);
		scmnd = csio_scsi_cmnd(ioreq);
		spin_unlock_irq(&hw->lock);

		/*
		 * Upper layers may have cleared this command, hence this
		 * check to avoid accessing stale references.
		 */
		if (scmnd != NULL)
			ioreq->io_cbfn(hw, ioreq);

		spin_lock_irq(&scm->freelist_lock);
		csio_put_scsi_ioreq(scm, ioreq);
		spin_unlock_irq(&scm->freelist_lock);

		spin_lock_irq(&hw->lock);
	}
}

#define CSIO_SCSI_ABORT_Q_POLL_MS		2000

static void
csio_abrt_cls(struct csio_ioreq *ioreq, struct scsi_cmnd *scmnd)
{
	struct csio_lnode *ln = ioreq->lnode;
	struct csio_hw *hw = ln->hwp;
	int ready = 0;
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);
	int rv;

	if (csio_scsi_cmnd(ioreq) != scmnd) {
		CSIO_INC_STATS(scsim, n_abrt_race_comp);
		return;
	}

	ready = csio_is_lnode_ready(ln);

	rv = csio_do_abrt_cls(hw, ioreq, (ready ? SCSI_ABORT : SCSI_CLOSE));
	if (rv != 0) {
		if (ready)
			CSIO_INC_STATS(scsim, n_abrt_busy_error);
		else
			CSIO_INC_STATS(scsim, n_cls_busy_error);
	}
}

/*
 * csio_scsi_abort_io_q - Abort all I/Os on given queue
 * @scm: SCSI module.
 * @q: Queue to abort.
 * @tmo: Timeout in ms
 *
 * Attempt to abort all I/Os on given queue, and wait for a max
 * of tmo milliseconds for them to complete. Returns success
 * if all I/Os are aborted. Else returns -ETIMEDOUT.
 * Should be entered with lock held. Exits with lock held.
 * NOTE:
 * Lock has to be held across the loop that aborts I/Os, since dropping the lock
 * in between can cause the list to be corrupted. As a result, the caller
 * of this function has to ensure that the number of I/os to be aborted
 * is finite enough to not cause lock-held-for-too-long issues.
 */
static int
csio_scsi_abort_io_q(struct csio_scsim *scm, struct list_head *q, uint32_t tmo)
{
	struct csio_hw *hw = scm->hw;
	struct list_head *tmp, *next;
	int count = DIV_ROUND_UP(tmo, CSIO_SCSI_ABORT_Q_POLL_MS);
	struct scsi_cmnd *scmnd;

	if (list_empty(q))
		return 0;

	csio_dbg(hw, "Aborting SCSI I/Os\n");

	/* Now abort/close I/Os in the queue passed */
	list_for_each_safe(tmp, next, q) {
		scmnd = csio_scsi_cmnd((struct csio_ioreq *)tmp);
		csio_abrt_cls((struct csio_ioreq *)tmp, scmnd);
	}

	/* Wait till all active I/Os are completed/aborted/closed */
	while (!list_empty(q) && count--) {
		spin_unlock_irq(&hw->lock);
		msleep(CSIO_SCSI_ABORT_Q_POLL_MS);
		spin_lock_irq(&hw->lock);
	}

	/* all aborts completed */
	if (list_empty(q))
		return 0;

	return -ETIMEDOUT;
}

/*
 * csio_scsim_cleanup_io - Cleanup all I/Os in SCSI module.
 * @scm: SCSI module.
 * @abort: abort required.
 * Called with lock held, should exit with lock held.
 * Can sleep when waiting for I/Os to complete.
 */
int
csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort)
{
	struct csio_hw *hw = scm->hw;
	int rv = 0;
	int count = DIV_ROUND_UP(60 * 1000, CSIO_SCSI_ABORT_Q_POLL_MS);

	/* No I/Os pending */
	if (list_empty(&scm->active_q))
		return 0;

	/* Wait until all active I/Os are completed */
	while (!list_empty(&scm->active_q) && count--) {
		spin_unlock_irq(&hw->lock);
		msleep(CSIO_SCSI_ABORT_Q_POLL_MS);
		spin_lock_irq(&hw->lock);
	}

	/* all I/Os completed */
	if (list_empty(&scm->active_q))
		return 0;

	/* Else abort */
	if (abort) {
		rv = csio_scsi_abort_io_q(scm, &scm->active_q, 30000);
		if (rv == 0)
			return rv;
		csio_dbg(hw, "Some I/O aborts timed out, cleaning up..\n");
	}

	csio_scsi_cleanup_io_q(scm, &scm->active_q);

	CSIO_DB_ASSERT(list_empty(&scm->active_q));

	return rv;
}

/*
 * csio_scsim_cleanup_io_lnode - Cleanup all I/Os of given lnode.
 * @scm: SCSI module.
 * @lnode: lnode
 *
 * Called with lock held, should exit with lock held.
 * Can sleep (with dropped lock) when waiting for I/Os to complete.
 */
int
csio_scsim_cleanup_io_lnode(struct csio_scsim *scm, struct csio_lnode *ln)
{
	struct csio_hw *hw = scm->hw;
	struct csio_scsi_level_data sld;
	int rv;
	int count = DIV_ROUND_UP(60 * 1000, CSIO_SCSI_ABORT_Q_POLL_MS);

	csio_dbg(hw, "Gathering all SCSI I/Os on lnode %p\n", ln);

	sld.level = CSIO_LEV_LNODE;
	sld.lnode = ln;
	INIT_LIST_HEAD(&ln->cmpl_q);
	csio_scsi_gather_active_ios(scm, &sld, &ln->cmpl_q);

	/* No I/Os pending on this lnode  */
	if (list_empty(&ln->cmpl_q))
		return 0;

	/* Wait until all active I/Os on this lnode are completed */
	while (!list_empty(&ln->cmpl_q) && count--) {
		spin_unlock_irq(&hw->lock);
		msleep(CSIO_SCSI_ABORT_Q_POLL_MS);
		spin_lock_irq(&hw->lock);
	}

	/* all I/Os completed */
	if (list_empty(&ln->cmpl_q))
		return 0;

	csio_dbg(hw, "Some I/Os pending on ln:%p, aborting them..\n", ln);

	/* I/Os are pending, abort them */
	rv = csio_scsi_abort_io_q(scm, &ln->cmpl_q, 30000);
	if (rv != 0) {
		csio_dbg(hw, "Some I/O aborts timed out, cleaning up..\n");
		csio_scsi_cleanup_io_q(scm, &ln->cmpl_q);
	}

	CSIO_DB_ASSERT(list_empty(&ln->cmpl_q));

	return rv;
}

static ssize_t
csio_show_hw_state(struct device *dev,
		   struct device_attribute *attr, char *buf)
{
	struct csio_lnode *ln = shost_priv(class_to_shost(dev));
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	if (csio_is_hw_ready(hw))
		return snprintf(buf, PAGE_SIZE, "ready\n");
	else
		return snprintf(buf, PAGE_SIZE, "not ready\n");
}

/* Device reset */
static ssize_t
csio_device_reset(struct device *dev,
		   struct device_attribute *attr, const char *buf, size_t count)
{
	struct csio_lnode *ln = shost_priv(class_to_shost(dev));
	struct csio_hw *hw = csio_lnode_to_hw(ln);

	if (*buf != '1')
		return -EINVAL;

	/* Delete NPIV lnodes */
	csio_lnodes_exit(hw, 1);

	/* Block upper IOs */
	csio_lnodes_block_request(hw);

	spin_lock_irq(&hw->lock);
	csio_hw_reset(hw);
	spin_unlock_irq(&hw->lock);

	/* Unblock upper IOs */
	csio_lnodes_unblock_request(hw);
	return count;
}

/* disable port */
static ssize_t
csio_disable_port(struct device *dev,
		   struct device_attribute *attr, const char *buf, size_t count)
{
	struct csio_lnode *ln = shost_priv(class_to_shost(dev));
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	bool disable;

	if (*buf == '1' || *buf == '0')
		disable = (*buf == '1') ? true : false;
	else
		return -EINVAL;

	/* Block upper IOs */
	csio_lnodes_block_by_port(hw, ln->portid);

	spin_lock_irq(&hw->lock);
	csio_disable_lnodes(hw, ln->portid, disable);
	spin_unlock_irq(&hw->lock);

	/* Unblock upper IOs */
	csio_lnodes_unblock_by_port(hw, ln->portid);
	return count;
}

/* Show debug level */
static ssize_t
csio_show_dbg_level(struct device *dev,
		   struct device_attribute *attr, char *buf)
{
	struct csio_lnode *ln = shost_priv(class_to_shost(dev));

	return snprintf(buf, PAGE_SIZE, "%x\n", ln->params.log_level);
}

/* Store debug level */
static ssize_t
csio_store_dbg_level(struct device *dev,
		   struct device_attribute *attr, const char *buf, size_t count)
{
	struct csio_lnode *ln = shost_priv(class_to_shost(dev));
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	uint32_t dbg_level = 0;

	if (!isdigit(buf[0]))
		return -EINVAL;

	if (sscanf(buf, "%i", &dbg_level))
		return -EINVAL;

	ln->params.log_level = dbg_level;
	hw->params.log_level = dbg_level;

	return 0;
}

static DEVICE_ATTR(hw_state, S_IRUGO, csio_show_hw_state, NULL);
static DEVICE_ATTR(device_reset, S_IWUSR, NULL, csio_device_reset);
static DEVICE_ATTR(disable_port, S_IWUSR, NULL, csio_disable_port);
static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
		  csio_store_dbg_level);

static struct attribute *csio_fcoe_lport_attrs[] = {
	&dev_attr_hw_state.attr,
	&dev_attr_device_reset.attr,
	&dev_attr_disable_port.attr,
	&dev_attr_dbg_level.attr,
	NULL,
};

ATTRIBUTE_GROUPS(csio_fcoe_lport);

static ssize_t
csio_show_num_reg_rnodes(struct device *dev,
		     struct device_attribute *attr, char *buf)
{
	struct csio_lnode *ln = shost_priv(class_to_shost(dev));

	return snprintf(buf, PAGE_SIZE, "%d\n", ln->num_reg_rnodes);
}

static DEVICE_ATTR(num_reg_rnodes, S_IRUGO, csio_show_num_reg_rnodes, NULL);

static struct attribute *csio_fcoe_vport_attrs[] = {
	&dev_attr_num_reg_rnodes.attr,
	&dev_attr_dbg_level.attr,
	NULL,
};

ATTRIBUTE_GROUPS(csio_fcoe_vport);

static inline uint32_t
csio_scsi_copy_to_sgl(struct csio_hw *hw, struct csio_ioreq *req)
{
	struct scsi_cmnd *scmnd  = (struct scsi_cmnd *)csio_scsi_cmnd(req);
	struct scatterlist *sg;
	uint32_t bytes_left;
	uint32_t bytes_copy;
	uint32_t buf_off = 0;
	uint32_t start_off = 0;
	uint32_t sg_off = 0;
	void *sg_addr;
	void *buf_addr;
	struct csio_dma_buf *dma_buf;

	bytes_left = scsi_bufflen(scmnd);
	sg = scsi_sglist(scmnd);
	dma_buf = (struct csio_dma_buf *)csio_list_next(&req->gen_list);

	/* Copy data from driver buffer to SGs of SCSI CMD */
	while (bytes_left > 0 && sg && dma_buf) {
		if (buf_off >= dma_buf->len) {
			buf_off = 0;
			dma_buf = (struct csio_dma_buf *)
					csio_list_next(dma_buf);
			continue;
		}

		if (start_off >= sg->length) {
			start_off -= sg->length;
			sg = sg_next(sg);
			continue;
		}

		buf_addr = dma_buf->vaddr + buf_off;
		sg_off = sg->offset + start_off;
		bytes_copy = min((dma_buf->len - buf_off),
				sg->length - start_off);
		bytes_copy = min((uint32_t)(PAGE_SIZE - (sg_off & ~PAGE_MASK)),
				 bytes_copy);

		sg_addr = kmap_atomic(sg_page(sg) + (sg_off >> PAGE_SHIFT));
		if (!sg_addr) {
			csio_err(hw, "failed to kmap sg:%p of ioreq:%p\n",
				sg, req);
			break;
		}

		csio_dbg(hw, "copy_to_sgl:sg_addr %p sg_off %d buf %p len %d\n",
				sg_addr, sg_off, buf_addr, bytes_copy);
		memcpy(sg_addr + (sg_off & ~PAGE_MASK), buf_addr, bytes_copy);
		kunmap_atomic(sg_addr);

		start_off +=  bytes_copy;
		buf_off += bytes_copy;
		bytes_left -= bytes_copy;
	}

	if (bytes_left > 0)
		return DID_ERROR;
	else
		return DID_OK;
}

/*
 * csio_scsi_err_handler - SCSI error handler.
 * @hw: HW module.
 * @req: IO request.
 *
 */
static inline void
csio_scsi_err_handler(struct csio_hw *hw, struct csio_ioreq *req)
{
	struct scsi_cmnd *cmnd  = (struct scsi_cmnd *)csio_scsi_cmnd(req);
	struct csio_scsim *scm = csio_hw_to_scsim(hw);
	struct fcp_resp_with_ext *fcp_resp;
	struct fcp_resp_rsp_info *rsp_info;
	struct csio_dma_buf *dma_buf;
	uint8_t flags, scsi_status = 0;
	uint32_t host_status = DID_OK;
	uint32_t rsp_len = 0, sns_len = 0;
	struct csio_rnode *rn = (struct csio_rnode *)(cmnd->device->hostdata);


	switch (req->wr_status) {
	case FW_HOSTERROR:
		if (unlikely(!csio_is_hw_ready(hw)))
			return;

		host_status = DID_ERROR;
		CSIO_INC_STATS(scm, n_hosterror);

		break;
	case FW_SCSI_RSP_ERR:
		dma_buf = &req->dma_buf;
		fcp_resp = (struct fcp_resp_with_ext *)dma_buf->vaddr;
		rsp_info = (struct fcp_resp_rsp_info *)(fcp_resp + 1);
		flags = fcp_resp->resp.fr_flags;
		scsi_status = fcp_resp->resp.fr_status;

		if (flags & FCP_RSP_LEN_VAL) {
			rsp_len = be32_to_cpu(fcp_resp->ext.fr_rsp_len);
			if ((rsp_len != 0 && rsp_len != 4 && rsp_len != 8) ||
				(rsp_info->rsp_code != FCP_TMF_CMPL)) {
				host_status = DID_ERROR;
				goto out;
			}
		}

		if ((flags & FCP_SNS_LEN_VAL) && fcp_resp->ext.fr_sns_len) {
			sns_len = be32_to_cpu(fcp_resp->ext.fr_sns_len);
			if (sns_len > SCSI_SENSE_BUFFERSIZE)
				sns_len = SCSI_SENSE_BUFFERSIZE;

			memcpy(cmnd->sense_buffer,
			       &rsp_info->_fr_resvd[0] + rsp_len, sns_len);
			CSIO_INC_STATS(scm, n_autosense);
		}

		scsi_set_resid(cmnd, 0);

		/* Under run */
		if (flags & FCP_RESID_UNDER) {
			scsi_set_resid(cmnd,
				       be32_to_cpu(fcp_resp->ext.fr_resid));

			if (!(flags & FCP_SNS_LEN_VAL) &&
			    (scsi_status == SAM_STAT_GOOD) &&
			    ((scsi_bufflen(cmnd) - scsi_get_resid(cmnd))
							< cmnd->underflow))
				host_status = DID_ERROR;
		} else if (flags & FCP_RESID_OVER)
			host_status = DID_ERROR;

		CSIO_INC_STATS(scm, n_rsperror);
		break;

	case FW_SCSI_OVER_FLOW_ERR:
		csio_warn(hw,
			  "Over-flow error,cmnd:0x%x expected len:0x%x"
			  " resid:0x%x\n", cmnd->cmnd[0],
			  scsi_bufflen(cmnd), scsi_get_resid(cmnd));
		host_status = DID_ERROR;
		CSIO_INC_STATS(scm, n_ovflerror);
		break;

	case FW_SCSI_UNDER_FLOW_ERR:
		csio_warn(hw,
			  "Under-flow error,cmnd:0x%x expected"
			  " len:0x%x resid:0x%x lun:0x%llx ssn:0x%x\n",
			  cmnd->cmnd[0], scsi_bufflen(cmnd),
			  scsi_get_resid(cmnd), cmnd->device->lun,
			  rn->flowid);
		host_status = DID_ERROR;
		CSIO_INC_STATS(scm, n_unflerror);
		break;

	case FW_SCSI_ABORT_REQUESTED:
	case FW_SCSI_ABORTED:
	case FW_SCSI_CLOSE_REQUESTED:
		csio_dbg(hw, "Req %p cmd:%p op:%x %s\n", req, cmnd,
			     cmnd->cmnd[0],
			    (req->wr_status == FW_SCSI_CLOSE_REQUESTED) ?
			    "closed" : "aborted");
		/*
		 * csio_eh_abort_handler checks this value to
		 * succeed or fail the abort request.
		 */
		host_status = DID_REQUEUE;
		if (req->wr_status == FW_SCSI_CLOSE_REQUESTED)
			CSIO_INC_STATS(scm, n_closed);
		else
			CSIO_INC_STATS(scm, n_aborted);
		break;

	case FW_SCSI_ABORT_TIMEDOUT:
		/* FW timed out the abort itself */
		csio_dbg(hw, "FW timed out abort req:%p cmnd:%p status:%x\n",
			 req, cmnd, req->wr_status);
		host_status = DID_ERROR;
		CSIO_INC_STATS(scm, n_abrt_timedout);
		break;

	case FW_RDEV_NOT_READY:
		/*
		 * In firmware, a RDEV can get into this state
		 * temporarily, before moving into dissapeared/lost
		 * state. So, the driver should complete the request equivalent
		 * to device-disappeared!
		 */
		CSIO_INC_STATS(scm, n_rdev_nr_error);
		host_status = DID_ERROR;
		break;

	case FW_ERR_RDEV_LOST:
		CSIO_INC_STATS(scm, n_rdev_lost_error);
		host_status = DID_ERROR;
		break;

	case FW_ERR_RDEV_LOGO:
		CSIO_INC_STATS(scm, n_rdev_logo_error);
		host_status = DID_ERROR;
		break;

	case FW_ERR_RDEV_IMPL_LOGO:
		host_status = DID_ERROR;
		break;

	case FW_ERR_LINK_DOWN:
		CSIO_INC_STATS(scm, n_link_down_error);
		host_status = DID_ERROR;
		break;

	case FW_FCOE_NO_XCHG:
		CSIO_INC_STATS(scm, n_no_xchg_error);
		host_status = DID_ERROR;
		break;

	default:
		csio_err(hw, "Unknown SCSI FW WR status:%d req:%p cmnd:%p\n",
			    req->wr_status, req, cmnd);
		CSIO_DB_ASSERT(0);

		CSIO_INC_STATS(scm, n_unknown_error);
		host_status = DID_ERROR;
		break;
	}

out:
	if (req->nsge > 0) {
		scsi_dma_unmap(cmnd);
		if (req->dcopy && (host_status == DID_OK))
			host_status = csio_scsi_copy_to_sgl(hw, req);
	}

	cmnd->result = (((host_status) << 16) | scsi_status);
	scsi_done(cmnd);

	/* Wake up waiting threads */
	csio_scsi_cmnd(req) = NULL;
	complete(&req->cmplobj);
}

/*
 * csio_scsi_cbfn - SCSI callback function.
 * @hw: HW module.
 * @req: IO request.
 *
 */
static void
csio_scsi_cbfn(struct csio_hw *hw, struct csio_ioreq *req)
{
	struct scsi_cmnd *cmnd  = (struct scsi_cmnd *)csio_scsi_cmnd(req);
	uint8_t scsi_status = SAM_STAT_GOOD;
	uint32_t host_status = DID_OK;

	if (likely(req->wr_status == FW_SUCCESS)) {
		if (req->nsge > 0) {
			scsi_dma_unmap(cmnd);
			if (req->dcopy)
				host_status = csio_scsi_copy_to_sgl(hw, req);
		}

		cmnd->result = (((host_status) << 16) | scsi_status);
		scsi_done(cmnd);
		csio_scsi_cmnd(req) = NULL;
		CSIO_INC_STATS(csio_hw_to_scsim(hw), n_tot_success);
	} else {
		/* Error handling */
		csio_scsi_err_handler(hw, req);
	}
}

/**
 * csio_queuecommand - Entry point to kickstart an I/O request.
 * @host:	The scsi_host pointer.
 * @cmnd:	The I/O request from ML.
 *
 * This routine does the following:
 *	- Checks for HW and Rnode module readiness.
 *	- Gets a free ioreq structure (which is already initialized
 *	  to uninit during its allocation).
 *	- Maps SG elements.
 *	- Initializes ioreq members.
 *	- Kicks off the SCSI state machine for this IO.
 *	- Returns busy status on error.
 */
static int
csio_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmnd)
{
	struct csio_lnode *ln = shost_priv(host);
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);
	struct csio_rnode *rn = (struct csio_rnode *)(cmnd->device->hostdata);
	struct csio_ioreq *ioreq = NULL;
	unsigned long flags;
	int nsge = 0;
	int rv = SCSI_MLQUEUE_HOST_BUSY, nr;
	int retval;
	struct csio_scsi_qset *sqset;
	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));

	sqset = &hw->sqset[ln->portid][blk_mq_rq_cpu(scsi_cmd_to_rq(cmnd))];

	nr = fc_remote_port_chkready(rport);
	if (nr) {
		cmnd->result = nr;
		CSIO_INC_STATS(scsim, n_rn_nr_error);
		goto err_done;
	}

	if (unlikely(!csio_is_hw_ready(hw))) {
		cmnd->result = (DID_REQUEUE << 16);
		CSIO_INC_STATS(scsim, n_hw_nr_error);
		goto err_done;
	}

	/* Get req->nsge, if there are SG elements to be mapped  */
	nsge = scsi_dma_map(cmnd);
	if (unlikely(nsge < 0)) {
		CSIO_INC_STATS(scsim, n_dmamap_error);
		goto err;
	}

	/* Do we support so many mappings? */
	if (unlikely(nsge > scsim->max_sge)) {
		csio_warn(hw,
			  "More SGEs than can be supported."
			  " SGEs: %d, Max SGEs: %d\n", nsge, scsim->max_sge);
		CSIO_INC_STATS(scsim, n_unsupp_sge_error);
		goto err_dma_unmap;
	}

	/* Get a free ioreq structure - SM is already set to uninit */
	ioreq = csio_get_scsi_ioreq_lock(hw, scsim);
	if (!ioreq) {
		csio_err(hw, "Out of I/O request elements. Active #:%d\n",
			 scsim->stats.n_active);
		CSIO_INC_STATS(scsim, n_no_req_error);
		goto err_dma_unmap;
	}

	ioreq->nsge		= nsge;
	ioreq->lnode		= ln;
	ioreq->rnode		= rn;
	ioreq->iq_idx		= sqset->iq_idx;
	ioreq->eq_idx		= sqset->eq_idx;
	ioreq->wr_status	= 0;
	ioreq->drv_status	= 0;
	csio_scsi_cmnd(ioreq)	= (void *)cmnd;
	ioreq->tmo		= 0;
	ioreq->datadir		= cmnd->sc_data_direction;

	if (cmnd->sc_data_direction == DMA_TO_DEVICE) {
		CSIO_INC_STATS(ln, n_output_requests);
		ln->stats.n_output_bytes += scsi_bufflen(cmnd);
	} else if (cmnd->sc_data_direction == DMA_FROM_DEVICE) {
		CSIO_INC_STATS(ln, n_input_requests);
		ln->stats.n_input_bytes += scsi_bufflen(cmnd);
	} else
		CSIO_INC_STATS(ln, n_control_requests);

	/* Set cbfn */
	ioreq->io_cbfn = csio_scsi_cbfn;

	/* Needed during abort */
	cmnd->host_scribble = (unsigned char *)ioreq;
	cmnd->SCp.Message = 0;

	/* Kick off SCSI IO SM on the ioreq */
	spin_lock_irqsave(&hw->lock, flags);
	retval = csio_scsi_start_io(ioreq);
	spin_unlock_irqrestore(&hw->lock, flags);

	if (retval != 0) {
		csio_err(hw, "ioreq: %p couldn't be started, status:%d\n",
			 ioreq, retval);
		CSIO_INC_STATS(scsim, n_busy_error);
		goto err_put_req;
	}

	return 0;

err_put_req:
	csio_put_scsi_ioreq_lock(hw, scsim, ioreq);
err_dma_unmap:
	if (nsge > 0)
		scsi_dma_unmap(cmnd);
err:
	return rv;

err_done:
	scsi_done(cmnd);
	return 0;
}

static int
csio_do_abrt_cls(struct csio_hw *hw, struct csio_ioreq *ioreq, bool abort)
{
	int rv;
	int cpu = smp_processor_id();
	struct csio_lnode *ln = ioreq->lnode;
	struct csio_scsi_qset *sqset = &hw->sqset[ln->portid][cpu];

	ioreq->tmo = CSIO_SCSI_ABRT_TMO_MS;
	/*
	 * Use current processor queue for posting the abort/close, but retain
	 * the ingress queue ID of the original I/O being aborted/closed - we
	 * need the abort/close completion to be received on the same queue
	 * as the original I/O.
	 */
	ioreq->eq_idx = sqset->eq_idx;

	if (abort == SCSI_ABORT)
		rv = csio_scsi_abort(ioreq);
	else
		rv = csio_scsi_close(ioreq);

	return rv;
}

static int
csio_eh_abort_handler(struct scsi_cmnd *cmnd)
{
	struct csio_ioreq *ioreq;
	struct csio_lnode *ln = shost_priv(cmnd->device->host);
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);
	int ready = 0, ret;
	unsigned long tmo = 0;
	int rv;
	struct csio_rnode *rn = (struct csio_rnode *)(cmnd->device->hostdata);

	ret = fc_block_scsi_eh(cmnd);
	if (ret)
		return ret;

	ioreq = (struct csio_ioreq *)cmnd->host_scribble;
	if (!ioreq)
		return SUCCESS;

	if (!rn)
		return FAILED;

	csio_dbg(hw,
		 "Request to abort ioreq:%p cmd:%p cdb:%08llx"
		 " ssni:0x%x lun:%llu iq:0x%x\n",
		ioreq, cmnd, *((uint64_t *)cmnd->cmnd), rn->flowid,
		cmnd->device->lun, csio_q_physiqid(hw, ioreq->iq_idx));

	if (((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) != cmnd) {
		CSIO_INC_STATS(scsim, n_abrt_race_comp);
		return SUCCESS;
	}

	ready = csio_is_lnode_ready(ln);
	tmo = CSIO_SCSI_ABRT_TMO_MS;

	reinit_completion(&ioreq->cmplobj);
	spin_lock_irq(&hw->lock);
	rv = csio_do_abrt_cls(hw, ioreq, (ready ? SCSI_ABORT : SCSI_CLOSE));
	spin_unlock_irq(&hw->lock);

	if (rv != 0) {
		if (rv == -EINVAL) {
			/* Return success, if abort/close request issued on
			 * already completed IO
			 */
			return SUCCESS;
		}
		if (ready)
			CSIO_INC_STATS(scsim, n_abrt_busy_error);
		else
			CSIO_INC_STATS(scsim, n_cls_busy_error);

		goto inval_scmnd;
	}

	wait_for_completion_timeout(&ioreq->cmplobj, msecs_to_jiffies(tmo));

	/* FW didnt respond to abort within our timeout */
	if (((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == cmnd) {

		csio_err(hw, "Abort timed out -- req: %p\n", ioreq);
		CSIO_INC_STATS(scsim, n_abrt_timedout);

inval_scmnd:
		if (ioreq->nsge > 0)
			scsi_dma_unmap(cmnd);

		spin_lock_irq(&hw->lock);
		csio_scsi_cmnd(ioreq) = NULL;
		spin_unlock_irq(&hw->lock);

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

		return FAILED;
	}

	/* FW successfully aborted the request */
	if (host_byte(cmnd->result) == DID_REQUEUE) {
		csio_info(hw,
			"Aborted SCSI command to (%d:%llu) tag %u\n",
			cmnd->device->id, cmnd->device->lun,
			scsi_cmd_to_rq(cmnd)->tag);
		return SUCCESS;
	} else {
		csio_info(hw,
			"Failed to abort SCSI command, (%d:%llu) tag %u\n",
			cmnd->device->id, cmnd->device->lun,
			scsi_cmd_to_rq(cmnd)->tag);
		return FAILED;
	}
}

/*
 * csio_tm_cbfn - TM callback function.
 * @hw: HW module.
 * @req: IO request.
 *
 * Cache the result in 'cmnd', since ioreq will be freed soon
 * after we return from here, and the waiting thread shouldnt trust
 * the ioreq contents.
 */
static void
csio_tm_cbfn(struct csio_hw *hw, struct csio_ioreq *req)
{
	struct scsi_cmnd *cmnd  = (struct scsi_cmnd *)csio_scsi_cmnd(req);
	struct csio_dma_buf *dma_buf;
	uint8_t flags = 0;
	struct fcp_resp_with_ext *fcp_resp;
	struct fcp_resp_rsp_info *rsp_info;

	csio_dbg(hw, "req: %p in csio_tm_cbfn status: %d\n",
		      req, req->wr_status);

	/* Cache FW return status */
	cmnd->SCp.Status = req->wr_status;

	/* Special handling based on FCP response */

	/*
	 * FW returns us this error, if flags were set. FCP4 says
	 * FCP_RSP_LEN_VAL in flags shall be set for TM completions.
	 * So if a target were to set this bit, we expect that the
	 * rsp_code is set to FCP_TMF_CMPL for a successful TM
	 * completion. Any other rsp_code means TM operation failed.
	 * If a target were to just ignore setting flags, we treat
	 * the TM operation as success, and FW returns FW_SUCCESS.
	 */
	if (req->wr_status == FW_SCSI_RSP_ERR) {
		dma_buf = &req->dma_buf;
		fcp_resp = (struct fcp_resp_with_ext *)dma_buf->vaddr;
		rsp_info = (struct fcp_resp_rsp_info *)(fcp_resp + 1);

		flags = fcp_resp->resp.fr_flags;

		/* Modify return status if flags indicate success */
		if (flags & FCP_RSP_LEN_VAL)
			if (rsp_info->rsp_code == FCP_TMF_CMPL)
				cmnd->SCp.Status = FW_SUCCESS;

		csio_dbg(hw, "TM FCP rsp code: %d\n", rsp_info->rsp_code);
	}

	/* Wake up the TM handler thread */
	csio_scsi_cmnd(req) = NULL;
}

static int
csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
{
	struct csio_lnode *ln = shost_priv(cmnd->device->host);
	struct csio_hw *hw = csio_lnode_to_hw(ln);
	struct csio_scsim *scsim = csio_hw_to_scsim(hw);
	struct csio_rnode *rn = (struct csio_rnode *)(cmnd->device->hostdata);
	struct csio_ioreq *ioreq = NULL;
	struct csio_scsi_qset *sqset;
	unsigned long flags;
	int retval;
	int count, ret;
	LIST_HEAD(local_q);
	struct csio_scsi_level_data sld;

	if (!rn)
		goto fail;

	csio_dbg(hw, "Request to reset LUN:%llu (ssni:0x%x tgtid:%d)\n",
		      cmnd->device->lun, rn->flowid, rn->scsi_id);

	if (!csio_is_lnode_ready(ln)) {
		csio_err(hw,
			 "LUN reset cannot be issued on non-ready"
			 " local node vnpi:0x%x (LUN:%llu)\n",
			 ln->vnp_flowid, cmnd->device->lun);
		goto fail;
	}

	/* Lnode is ready, now wait on rport node readiness */
	ret = fc_block_scsi_eh(cmnd);
	if (ret)
		return ret;

	/*
	 * If we have blocked in the previous call, at this point, either the
	 * remote node has come back online, or device loss timer has fired
	 * and the remote node is destroyed. Allow the LUN reset only for
	 * the former case, since LUN reset is a TMF I/O on the wire, and we
	 * need a valid session to issue it.
	 */
	if (fc_remote_port_chkready(rn->rport)) {
		csio_err(hw,
			 "LUN reset cannot be issued on non-ready"
			 " remote node ssni:0x%x (LUN:%llu)\n",
			 rn->flowid, cmnd->device->lun);
		goto fail;
	}

	/* Get a free ioreq structure - SM is already set to uninit */
	ioreq = csio_get_scsi_ioreq_lock(hw, scsim);

	if (!ioreq) {
		csio_err(hw, "Out of IO request elements. Active # :%d\n",
			 scsim->stats.n_active);
		goto fail;
	}

	sqset			= &hw->sqset[ln->portid][smp_processor_id()];
	ioreq->nsge		= 0;
	ioreq->lnode		= ln;
	ioreq->rnode		= rn;
	ioreq->iq_idx		= sqset->iq_idx;
	ioreq->eq_idx		= sqset->eq_idx;

	csio_scsi_cmnd(ioreq)	= cmnd;
	cmnd->host_scribble	= (unsigned char *)ioreq;
	cmnd->SCp.Status	= 0;

	cmnd->SCp.Message	= FCP_TMF_LUN_RESET;
	ioreq->tmo		= CSIO_SCSI_LUNRST_TMO_MS / 1000;

	/*
	 * FW times the LUN reset for ioreq->tmo, so we got to wait a little
	 * longer (10s for now) than that to allow FW to return the timed
	 * out command.
	 */
	count = DIV_ROUND_UP((ioreq->tmo + 10) * 1000, CSIO_SCSI_TM_POLL_MS);

	/* Set cbfn */
	ioreq->io_cbfn = csio_tm_cbfn;

	/* Save of the ioreq info for later use */
	sld.level = CSIO_LEV_LUN;
	sld.lnode = ioreq->lnode;
	sld.rnode = ioreq->rnode;
	sld.oslun = cmnd->device->lun;

	spin_lock_irqsave(&hw->lock, flags);
	/* Kick off TM SM on the ioreq */
	retval = csio_scsi_start_tm(ioreq);
	spin_unlock_irqrestore(&hw->lock, flags);

	if (retval != 0) {
		csio_err(hw, "Failed to issue LUN reset, req:%p, status:%d\n",
			    ioreq, retval);
		goto fail_ret_ioreq;
	}

	csio_dbg(hw, "Waiting max %d secs for LUN reset completion\n",
		    count * (CSIO_SCSI_TM_POLL_MS / 1000));
	/* Wait for completion */
	while ((((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == cmnd)
								&& count--)
		msleep(CSIO_SCSI_TM_POLL_MS);

	/* LUN reset timed-out */
	if (((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == cmnd) {
		csio_err(hw, "LUN reset (%d:%llu) timed out\n",
			 cmnd->device->id, cmnd->device->lun);

		spin_lock_irq(&hw->lock);
		csio_scsi_drvcleanup(ioreq);
		list_del_init(&ioreq->sm.sm_list);
		spin_unlock_irq(&hw->lock);

		goto fail_ret_ioreq;
	}

	/* LUN reset returned, check cached status */
	if (cmnd->SCp.Status != FW_SUCCESS) {
		csio_err(hw, "LUN reset failed (%d:%llu), status: %d\n",
			 cmnd->device->id, cmnd->device->lun, cmnd->SCp.Status);
		goto fail;
	}

	/* LUN reset succeeded, Start aborting affected I/Os */
	/*
	 * Since the host guarantees during LUN reset that there
	 * will not be any more I/Os to that LUN, until the LUN reset
	 * completes, we gather pending I/Os after the LUN reset.
	 */
	spin_lock_irq(&hw->lock);
	csio_scsi_gather_active_ios(scsim, &sld, &local_q);

	retval = csio_scsi_abort_io_q(scsim, &local_q, 30000);
	spin_unlock_irq(&hw->lock);

	/* Aborts may have timed out */
	if (retval != 0) {
		csio_err(hw,
			 "Attempt to abort I/Os during LUN reset of %llu"
			 " returned %d\n", cmnd->device->lun, retval);
		/* Return I/Os back to active_q */
		spin_lock_irq(&hw->lock);
		list_splice_tail_init(&local_q, &scsim->active_q);
		spin_unlock_irq(&hw->lock);
		goto fail;
	}

	CSIO_INC_STATS(rn, n_lun_rst);

	csio_info(hw, "LUN reset occurred (%d:%llu)\n",
		  cmnd->device->id, cmnd->device->lun);

	return SUCCESS;

fail_ret_ioreq:
	csio_put_scsi_ioreq_lock(hw, scsim, ioreq);
fail:
	CSIO_INC_STATS(rn, n_lun_rst_fail);
	return FAILED;
}

static int
csio_slave_alloc(struct scsi_device *sdev)
{
	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));

	if (!rport || fc_remote_port_chkready(rport))
		return -ENXIO;

	sdev->hostdata = *((struct csio_lnode **)(rport->dd_data));

	return 0;
}

static int
csio_slave_configure(struct scsi_device *sdev)
{
	scsi_change_queue_depth(sdev, csio_lun_qdepth);
	return 0;
}

static void
csio_slave_destroy(struct scsi_device *sdev)
{
	sdev->hostdata = NULL;
}

static int
csio_scan_finished(struct Scsi_Host *shost, unsigned long time)
{
	struct csio_lnode *ln = shost_priv(shost);
	int rv = 1;

	spin_lock_irq(shost->host_lock);
	if (!ln->hwp || csio_list_deleted(&ln->sm.sm_list))
		goto out;

	rv = csio_scan_done(ln, jiffies, time, csio_max_scan_tmo * HZ,
			    csio_delta_scan_tmo * HZ);
out:
	spin_unlock_irq(shost->host_lock);

	return rv;
}

struct scsi_host_template csio_fcoe_shost_template = {
	.module			= THIS_MODULE,
	.name			= CSIO_DRV_DESC,
	.proc_name		= KBUILD_MODNAME,
	.queuecommand		= csio_queuecommand,
	.eh_timed_out		= fc_eh_timed_out,
	.eh_abort_handler	= csio_eh_abort_handler,
	.eh_device_reset_handler = csio_eh_lun_reset_handler,
	.slave_alloc		= csio_slave_alloc,
	.slave_configure	= csio_slave_configure,
	.slave_destroy		= csio_slave_destroy,
	.scan_finished		= csio_scan_finished,
	.this_id		= -1,
	.sg_tablesize		= CSIO_SCSI_MAX_SGE,
	.cmd_per_lun		= CSIO_MAX_CMD_PER_LUN,
	.shost_groups		= csio_fcoe_lport_groups,
	.max_sectors		= CSIO_MAX_SECTOR_SIZE,
};

struct scsi_host_template csio_fcoe_shost_vport_template = {
	.module			= THIS_MODULE,
	.name			= CSIO_DRV_DESC,
	.proc_name		= KBUILD_MODNAME,
	.queuecommand		= csio_queuecommand,
	.eh_timed_out		= fc_eh_timed_out,
	.eh_abort_handler	= csio_eh_abort_handler,
	.eh_device_reset_handler = csio_eh_lun_reset_handler,
	.slave_alloc		= csio_slave_alloc,
	.slave_configure	= csio_slave_configure,
	.slave_destroy		= csio_slave_destroy,
	.scan_finished		= csio_scan_finished,
	.this_id		= -1,
	.sg_tablesize		= CSIO_SCSI_MAX_SGE,
	.cmd_per_lun		= CSIO_MAX_CMD_PER_LUN,
	.shost_groups		= csio_fcoe_vport_groups,
	.max_sectors		= CSIO_MAX_SECTOR_SIZE,
};

/*
 * csio_scsi_alloc_ddp_bufs - Allocate buffers for DDP of unaligned SGLs.
 * @scm: SCSI Module
 * @hw: HW device.
 * @buf_size: buffer size
 * @num_buf : Number of buffers.
 *
 * This routine allocates DMA buffers required for SCSI Data xfer, if
 * each SGL buffer for a SCSI Read request posted by SCSI midlayer are
 * not virtually contiguous.
 */
static int
csio_scsi_alloc_ddp_bufs(struct csio_scsim *scm, struct csio_hw *hw,
			 int buf_size, int num_buf)
{
	int n = 0;
	struct list_head *tmp;
	struct csio_dma_buf *ddp_desc = NULL;
	uint32_t unit_size = 0;

	if (!num_buf)
		return 0;

	if (!buf_size)
		return -EINVAL;

	INIT_LIST_HEAD(&scm->ddp_freelist);

	/* Align buf size to page size */
	buf_size = (buf_size + PAGE_SIZE - 1) & PAGE_MASK;
	/* Initialize dma descriptors */
	for (n = 0; n < num_buf; n++) {
		/* Set unit size to request size */
		unit_size = buf_size;
		ddp_desc = kzalloc(sizeof(struct csio_dma_buf), GFP_KERNEL);
		if (!ddp_desc) {
			csio_err(hw,
				 "Failed to allocate ddp descriptors,"
				 " Num allocated = %d.\n",
				 scm->stats.n_free_ddp);
			goto no_mem;
		}

		/* Allocate Dma buffers for DDP */
		ddp_desc->vaddr = dma_alloc_coherent(&hw->pdev->dev, unit_size,
				&ddp_desc->paddr, GFP_KERNEL);
		if (!ddp_desc->vaddr) {
			csio_err(hw,
				 "SCSI response DMA buffer (ddp) allocation"
				 " failed!\n");
			kfree(ddp_desc);
			goto no_mem;
		}

		ddp_desc->len = unit_size;

		/* Added it to scsi ddp freelist */
		list_add_tail(&ddp_desc->list, &scm->ddp_freelist);
		CSIO_INC_STATS(scm, n_free_ddp);
	}

	return 0;
no_mem:
	/* release dma descs back to freelist and free dma memory */
	list_for_each(tmp, &scm->ddp_freelist) {
		ddp_desc = (struct csio_dma_buf *) tmp;
		tmp = csio_list_prev(tmp);
		dma_free_coherent(&hw->pdev->dev, ddp_desc->len,
				  ddp_desc->vaddr, ddp_desc->paddr);
		list_del_init(&ddp_desc->list);
		kfree(ddp_desc);
	}
	scm->stats.n_free_ddp = 0;

	return -ENOMEM;
}

/*
 * csio_scsi_free_ddp_bufs - free DDP buffers of unaligned SGLs.
 * @scm: SCSI Module
 * @hw: HW device.
 *
 * This routine frees ddp buffers.
 */
static void
csio_scsi_free_ddp_bufs(struct csio_scsim *scm, struct csio_hw *hw)
{
	struct list_head *tmp;
	struct csio_dma_buf *ddp_desc;

	/* release dma descs back to freelist and free dma memory */
	list_for_each(tmp, &scm->ddp_freelist) {
		ddp_desc = (struct csio_dma_buf *) tmp;
		tmp = csio_list_prev(tmp);
		dma_free_coherent(&hw->pdev->dev, ddp_desc->len,
				  ddp_desc->vaddr, ddp_desc->paddr);
		list_del_init(&ddp_desc->list);
		kfree(ddp_desc);
	}
	scm->stats.n_free_ddp = 0;
}

/**
 * csio_scsim_init - Initialize SCSI Module
 * @scm:	SCSI Module
 * @hw:		HW module
 *
 */
int
csio_scsim_init(struct csio_scsim *scm, struct csio_hw *hw)
{
	int i;
	struct csio_ioreq *ioreq;
	struct csio_dma_buf *dma_buf;

	INIT_LIST_HEAD(&scm->active_q);
	scm->hw = hw;

	scm->proto_cmd_len = sizeof(struct fcp_cmnd);
	scm->proto_rsp_len = CSIO_SCSI_RSP_LEN;
	scm->max_sge = CSIO_SCSI_MAX_SGE;

	spin_lock_init(&scm->freelist_lock);

	/* Pre-allocate ioreqs and initialize them */
	INIT_LIST_HEAD(&scm->ioreq_freelist);
	for (i = 0; i < csio_scsi_ioreqs; i++) {

		ioreq = kzalloc(sizeof(struct csio_ioreq), GFP_KERNEL);
		if (!ioreq) {
			csio_err(hw,
				 "I/O request element allocation failed, "
				 " Num allocated = %d.\n",
				 scm->stats.n_free_ioreq);

			goto free_ioreq;
		}

		/* Allocate Dma buffers for Response Payload */
		dma_buf = &ioreq->dma_buf;
		dma_buf->vaddr = dma_pool_alloc(hw->scsi_dma_pool, GFP_KERNEL,
						&dma_buf->paddr);
		if (!dma_buf->vaddr) {
			csio_err(hw,
				 "SCSI response DMA buffer allocation"
				 " failed!\n");
			kfree(ioreq);
			goto free_ioreq;
		}

		dma_buf->len = scm->proto_rsp_len;

		/* Set state to uninit */
		csio_init_state(&ioreq->sm, csio_scsis_uninit);
		INIT_LIST_HEAD(&ioreq->gen_list);
		init_completion(&ioreq->cmplobj);

		list_add_tail(&ioreq->sm.sm_list, &scm->ioreq_freelist);
		CSIO_INC_STATS(scm, n_free_ioreq);
	}

	if (csio_scsi_alloc_ddp_bufs(scm, hw, PAGE_SIZE, csio_ddp_descs))
		goto free_ioreq;

	return 0;

free_ioreq:
	/*
	 * Free up existing allocations, since an error
	 * from here means we are returning for good
	 */
	while (!list_empty(&scm->ioreq_freelist)) {
		struct csio_sm *tmp;

		tmp = list_first_entry(&scm->ioreq_freelist,
				       struct csio_sm, sm_list);
		list_del_init(&tmp->sm_list);
		ioreq = (struct csio_ioreq *)tmp;

		dma_buf = &ioreq->dma_buf;
		dma_pool_free(hw->scsi_dma_pool, dma_buf->vaddr,
			      dma_buf->paddr);

		kfree(ioreq);
	}

	scm->stats.n_free_ioreq = 0;

	return -ENOMEM;
}

/**
 * csio_scsim_exit: Uninitialize SCSI Module
 * @scm: SCSI Module
 *
 */
void
csio_scsim_exit(struct csio_scsim *scm)
{
	struct csio_ioreq *ioreq;
	struct csio_dma_buf *dma_buf;

	while (!list_empty(&scm->ioreq_freelist)) {
		struct csio_sm *tmp;

		tmp = list_first_entry(&scm->ioreq_freelist,
				       struct csio_sm, sm_list);
		list_del_init(&tmp->sm_list);
		ioreq = (struct csio_ioreq *)tmp;

		dma_buf = &ioreq->dma_buf;
		dma_pool_free(scm->hw->scsi_dma_pool, dma_buf->vaddr,
			      dma_buf->paddr);

		kfree(ioreq);
	}

	scm->stats.n_free_ioreq = 0;

	csio_scsi_free_ddp_bufs(scm, scm->hw);
}
