/* bnx2fc_io.c: QLogic Linux FCoE offload driver.
 * IO manager and SCSI IO processing.
 *
 * Copyright (c) 2008-2013 Broadcom Corporation
 * Copyright (c) 2014-2015 QLogic Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Written by: Bhanu Prakash Gollapudi (bprakash@broadcom.com)
 */

#include "bnx2fc.h"

#define RESERVE_FREE_LIST_INDEX num_possible_cpus()

static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len,
			   int bd_index);
static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req);
static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req);
static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req);
static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req);
static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req,
				 struct fcoe_fcp_rsp_payload *fcp_rsp,
				 u8 num_rq);

void bnx2fc_cmd_timer_set(struct bnx2fc_cmd *io_req,
			  unsigned int timer_msec)
{
	struct bnx2fc_interface *interface = io_req->port->priv;

	if (queue_delayed_work(interface->timer_work_queue,
			       &io_req->timeout_work,
			       msecs_to_jiffies(timer_msec)))
		kref_get(&io_req->refcount);
}

static void bnx2fc_cmd_timeout(struct work_struct *work)
{
	struct bnx2fc_cmd *io_req = container_of(work, struct bnx2fc_cmd,
						 timeout_work.work);
	u8 cmd_type = io_req->cmd_type;
	struct bnx2fc_rport *tgt = io_req->tgt;
	int rc;

	BNX2FC_IO_DBG(io_req, "cmd_timeout, cmd_type = %d,"
		      "req_flags = %lx\n", cmd_type, io_req->req_flags);

	spin_lock_bh(&tgt->tgt_lock);
	if (test_and_clear_bit(BNX2FC_FLAG_ISSUE_RRQ, &io_req->req_flags)) {
		clear_bit(BNX2FC_FLAG_RETIRE_OXID, &io_req->req_flags);
		/*
		 * ideally we should hold the io_req until RRQ complets,
		 * and release io_req from timeout hold.
		 */
		spin_unlock_bh(&tgt->tgt_lock);
		bnx2fc_send_rrq(io_req);
		return;
	}
	if (test_and_clear_bit(BNX2FC_FLAG_RETIRE_OXID, &io_req->req_flags)) {
		BNX2FC_IO_DBG(io_req, "IO ready for reuse now\n");
		goto done;
	}

	switch (cmd_type) {
	case BNX2FC_SCSI_CMD:
		if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT,
							&io_req->req_flags)) {
			/* Handle eh_abort timeout */
			BNX2FC_IO_DBG(io_req, "eh_abort timed out\n");
			complete(&io_req->tm_done);
		} else if (test_bit(BNX2FC_FLAG_ISSUE_ABTS,
				    &io_req->req_flags)) {
			/* Handle internally generated ABTS timeout */
			BNX2FC_IO_DBG(io_req, "ABTS timed out refcnt = %d\n",
					io_req->refcount.refcount.counter);
			if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
					       &io_req->req_flags))) {
				/*
				 * Cleanup and return original command to
				 * mid-layer.
				 */
				bnx2fc_initiate_cleanup(io_req);
				kref_put(&io_req->refcount, bnx2fc_cmd_release);
				spin_unlock_bh(&tgt->tgt_lock);

				return;
			}
		} else {
			/* Hanlde IO timeout */
			BNX2FC_IO_DBG(io_req, "IO timed out. issue ABTS\n");
			if (test_and_set_bit(BNX2FC_FLAG_IO_COMPL,
					     &io_req->req_flags)) {
				BNX2FC_IO_DBG(io_req, "IO completed before "
							   " timer expiry\n");
				goto done;
			}

			if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS,
					      &io_req->req_flags)) {
				rc = bnx2fc_initiate_abts(io_req);
				if (rc == SUCCESS)
					goto done;

				kref_put(&io_req->refcount, bnx2fc_cmd_release);
				spin_unlock_bh(&tgt->tgt_lock);

				return;
			} else {
				BNX2FC_IO_DBG(io_req, "IO already in "
						      "ABTS processing\n");
			}
		}
		break;
	case BNX2FC_ELS:

		if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) {
			BNX2FC_IO_DBG(io_req, "ABTS for ELS timed out\n");

			if (!test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
					      &io_req->req_flags)) {
				kref_put(&io_req->refcount, bnx2fc_cmd_release);
				spin_unlock_bh(&tgt->tgt_lock);

				return;
			}
		} else {
			/*
			 * Handle ELS timeout.
			 * tgt_lock is used to sync compl path and timeout
			 * path. If els compl path is processing this IO, we
			 * have nothing to do here, just release the timer hold
			 */
			BNX2FC_IO_DBG(io_req, "ELS timed out\n");
			if (test_and_set_bit(BNX2FC_FLAG_ELS_DONE,
					       &io_req->req_flags))
				goto done;

			/* Indicate the cb_func that this ELS is timed out */
			set_bit(BNX2FC_FLAG_ELS_TIMEOUT, &io_req->req_flags);

			if ((io_req->cb_func) && (io_req->cb_arg)) {
				io_req->cb_func(io_req->cb_arg);
				io_req->cb_arg = NULL;
			}
		}
		break;
	default:
		printk(KERN_ERR PFX "cmd_timeout: invalid cmd_type %d\n",
			cmd_type);
		break;
	}

done:
	/* release the cmd that was held when timer was set */
	kref_put(&io_req->refcount, bnx2fc_cmd_release);
	spin_unlock_bh(&tgt->tgt_lock);
}

static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code)
{
	/* Called with host lock held */
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;

	/*
	 * active_cmd_queue may have other command types as well,
	 * and during flush operation,  we want to error back only
	 * scsi commands.
	 */
	if (io_req->cmd_type != BNX2FC_SCSI_CMD)
		return;

	BNX2FC_IO_DBG(io_req, "scsi_done. err_code = 0x%x\n", err_code);
	if (test_bit(BNX2FC_FLAG_CMD_LOST, &io_req->req_flags)) {
		/* Do not call scsi done for this IO */
		return;
	}

	bnx2fc_unmap_sg_list(io_req);
	io_req->sc_cmd = NULL;

	/* Sanity checks before returning command to mid-layer */
	if (!sc_cmd) {
		printk(KERN_ERR PFX "scsi_done - sc_cmd NULL. "
				    "IO(0x%x) already cleaned up\n",
		       io_req->xid);
		return;
	}
	if (!sc_cmd->device) {
		pr_err(PFX "0x%x: sc_cmd->device is NULL.\n", io_req->xid);
		return;
	}
	if (!sc_cmd->device->host) {
		pr_err(PFX "0x%x: sc_cmd->device->host is NULL.\n",
		    io_req->xid);
		return;
	}

	sc_cmd->result = err_code << 16;

	BNX2FC_IO_DBG(io_req, "sc=%p, result=0x%x, retries=%d, allowed=%d\n",
		sc_cmd, host_byte(sc_cmd->result), sc_cmd->retries,
		sc_cmd->allowed);
	scsi_set_resid(sc_cmd, scsi_bufflen(sc_cmd));
	sc_cmd->SCp.ptr = NULL;
	sc_cmd->scsi_done(sc_cmd);
}

struct bnx2fc_cmd_mgr *bnx2fc_cmd_mgr_alloc(struct bnx2fc_hba *hba)
{
	struct bnx2fc_cmd_mgr *cmgr;
	struct io_bdt *bdt_info;
	struct bnx2fc_cmd *io_req;
	size_t len;
	u32 mem_size;
	u16 xid;
	int i;
	int num_ios, num_pri_ios;
	size_t bd_tbl_sz;
	int arr_sz = num_possible_cpus() + 1;
	u16 min_xid = BNX2FC_MIN_XID;
	u16 max_xid = hba->max_xid;

	if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN) {
		printk(KERN_ERR PFX "cmd_mgr_alloc: Invalid min_xid 0x%x \
					and max_xid 0x%x\n", min_xid, max_xid);
		return NULL;
	}
	BNX2FC_MISC_DBG("min xid 0x%x, max xid 0x%x\n", min_xid, max_xid);

	num_ios = max_xid - min_xid + 1;
	len = (num_ios * (sizeof(struct bnx2fc_cmd *)));
	len += sizeof(struct bnx2fc_cmd_mgr);

	cmgr = kzalloc(len, GFP_KERNEL);
	if (!cmgr) {
		printk(KERN_ERR PFX "failed to alloc cmgr\n");
		return NULL;
	}

	cmgr->free_list = kzalloc(sizeof(*cmgr->free_list) *
				  arr_sz, GFP_KERNEL);
	if (!cmgr->free_list) {
		printk(KERN_ERR PFX "failed to alloc free_list\n");
		goto mem_err;
	}

	cmgr->free_list_lock = kzalloc(sizeof(*cmgr->free_list_lock) *
				       arr_sz, GFP_KERNEL);
	if (!cmgr->free_list_lock) {
		printk(KERN_ERR PFX "failed to alloc free_list_lock\n");
		kfree(cmgr->free_list);
		cmgr->free_list = NULL;
		goto mem_err;
	}

	cmgr->hba = hba;
	cmgr->cmds = (struct bnx2fc_cmd **)(cmgr + 1);

	for (i = 0; i < arr_sz; i++)  {
		INIT_LIST_HEAD(&cmgr->free_list[i]);
		spin_lock_init(&cmgr->free_list_lock[i]);
	}

	/*
	 * Pre-allocated pool of bnx2fc_cmds.
	 * Last entry in the free list array is the free list
	 * of slow path requests.
	 */
	xid = BNX2FC_MIN_XID;
	num_pri_ios = num_ios - hba->elstm_xids;
	for (i = 0; i < num_ios; i++) {
		io_req = kzalloc(sizeof(*io_req), GFP_KERNEL);

		if (!io_req) {
			printk(KERN_ERR PFX "failed to alloc io_req\n");
			goto mem_err;
		}

		INIT_LIST_HEAD(&io_req->link);
		INIT_DELAYED_WORK(&io_req->timeout_work, bnx2fc_cmd_timeout);

		io_req->xid = xid++;
		if (i < num_pri_ios)
			list_add_tail(&io_req->link,
				&cmgr->free_list[io_req->xid %
						 num_possible_cpus()]);
		else
			list_add_tail(&io_req->link,
				&cmgr->free_list[num_possible_cpus()]);
		io_req++;
	}

	/* Allocate pool of io_bdts - one for each bnx2fc_cmd */
	mem_size = num_ios * sizeof(struct io_bdt *);
	cmgr->io_bdt_pool = kmalloc(mem_size, GFP_KERNEL);
	if (!cmgr->io_bdt_pool) {
		printk(KERN_ERR PFX "failed to alloc io_bdt_pool\n");
		goto mem_err;
	}

	mem_size = sizeof(struct io_bdt);
	for (i = 0; i < num_ios; i++) {
		cmgr->io_bdt_pool[i] = kmalloc(mem_size, GFP_KERNEL);
		if (!cmgr->io_bdt_pool[i]) {
			printk(KERN_ERR PFX "failed to alloc "
				"io_bdt_pool[%d]\n", i);
			goto mem_err;
		}
	}

	/* Allocate an map fcoe_bdt_ctx structures */
	bd_tbl_sz = BNX2FC_MAX_BDS_PER_CMD * sizeof(struct fcoe_bd_ctx);
	for (i = 0; i < num_ios; i++) {
		bdt_info = cmgr->io_bdt_pool[i];
		bdt_info->bd_tbl = dma_alloc_coherent(&hba->pcidev->dev,
						      bd_tbl_sz,
						      &bdt_info->bd_tbl_dma,
						      GFP_KERNEL);
		if (!bdt_info->bd_tbl) {
			printk(KERN_ERR PFX "failed to alloc "
				"bdt_tbl[%d]\n", i);
			goto mem_err;
		}
	}

	return cmgr;

mem_err:
	bnx2fc_cmd_mgr_free(cmgr);
	return NULL;
}

void bnx2fc_cmd_mgr_free(struct bnx2fc_cmd_mgr *cmgr)
{
	struct io_bdt *bdt_info;
	struct bnx2fc_hba *hba = cmgr->hba;
	size_t bd_tbl_sz;
	u16 min_xid = BNX2FC_MIN_XID;
	u16 max_xid = hba->max_xid;
	int num_ios;
	int i;

	num_ios = max_xid - min_xid + 1;

	/* Free fcoe_bdt_ctx structures */
	if (!cmgr->io_bdt_pool)
		goto free_cmd_pool;

	bd_tbl_sz = BNX2FC_MAX_BDS_PER_CMD * sizeof(struct fcoe_bd_ctx);
	for (i = 0; i < num_ios; i++) {
		bdt_info = cmgr->io_bdt_pool[i];
		if (bdt_info->bd_tbl) {
			dma_free_coherent(&hba->pcidev->dev, bd_tbl_sz,
					    bdt_info->bd_tbl,
					    bdt_info->bd_tbl_dma);
			bdt_info->bd_tbl = NULL;
		}
	}

	/* Destroy io_bdt pool */
	for (i = 0; i < num_ios; i++) {
		kfree(cmgr->io_bdt_pool[i]);
		cmgr->io_bdt_pool[i] = NULL;
	}

	kfree(cmgr->io_bdt_pool);
	cmgr->io_bdt_pool = NULL;

free_cmd_pool:
	kfree(cmgr->free_list_lock);

	/* Destroy cmd pool */
	if (!cmgr->free_list)
		goto free_cmgr;

	for (i = 0; i < num_possible_cpus() + 1; i++)  {
		struct bnx2fc_cmd *tmp, *io_req;

		list_for_each_entry_safe(io_req, tmp,
					 &cmgr->free_list[i], link) {
			list_del(&io_req->link);
			kfree(io_req);
		}
	}
	kfree(cmgr->free_list);
free_cmgr:
	/* Free command manager itself */
	kfree(cmgr);
}

struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type)
{
	struct fcoe_port *port = tgt->port;
	struct bnx2fc_interface *interface = port->priv;
	struct bnx2fc_cmd_mgr *cmd_mgr = interface->hba->cmd_mgr;
	struct bnx2fc_cmd *io_req;
	struct list_head *listp;
	struct io_bdt *bd_tbl;
	int index = RESERVE_FREE_LIST_INDEX;
	u32 free_sqes;
	u32 max_sqes;
	u16 xid;

	max_sqes = tgt->max_sqes;
	switch (type) {
	case BNX2FC_TASK_MGMT_CMD:
		max_sqes = BNX2FC_TM_MAX_SQES;
		break;
	case BNX2FC_ELS:
		max_sqes = BNX2FC_ELS_MAX_SQES;
		break;
	default:
		break;
	}

	/*
	 * NOTE: Free list insertions and deletions are protected with
	 * cmgr lock
	 */
	spin_lock_bh(&cmd_mgr->free_list_lock[index]);
	free_sqes = atomic_read(&tgt->free_sqes);
	if ((list_empty(&(cmd_mgr->free_list[index]))) ||
	    (tgt->num_active_ios.counter  >= max_sqes) ||
	    (free_sqes + max_sqes <= BNX2FC_SQ_WQES_MAX)) {
		BNX2FC_TGT_DBG(tgt, "No free els_tm cmds available "
			"ios(%d):sqes(%d)\n",
			tgt->num_active_ios.counter, tgt->max_sqes);
		if (list_empty(&(cmd_mgr->free_list[index])))
			printk(KERN_ERR PFX "elstm_alloc: list_empty\n");
		spin_unlock_bh(&cmd_mgr->free_list_lock[index]);
		return NULL;
	}

	listp = (struct list_head *)
			cmd_mgr->free_list[index].next;
	list_del_init(listp);
	io_req = (struct bnx2fc_cmd *) listp;
	xid = io_req->xid;
	cmd_mgr->cmds[xid] = io_req;
	atomic_inc(&tgt->num_active_ios);
	atomic_dec(&tgt->free_sqes);
	spin_unlock_bh(&cmd_mgr->free_list_lock[index]);

	INIT_LIST_HEAD(&io_req->link);

	io_req->port = port;
	io_req->cmd_mgr = cmd_mgr;
	io_req->req_flags = 0;
	io_req->cmd_type = type;

	/* Bind io_bdt for this io_req */
	/* Have a static link between io_req and io_bdt_pool */
	bd_tbl = io_req->bd_tbl = cmd_mgr->io_bdt_pool[xid];
	bd_tbl->io_req = io_req;

	/* Hold the io_req  against deletion */
	kref_init(&io_req->refcount);
	return io_req;
}

struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt)
{
	struct fcoe_port *port = tgt->port;
	struct bnx2fc_interface *interface = port->priv;
	struct bnx2fc_cmd_mgr *cmd_mgr = interface->hba->cmd_mgr;
	struct bnx2fc_cmd *io_req;
	struct list_head *listp;
	struct io_bdt *bd_tbl;
	u32 free_sqes;
	u32 max_sqes;
	u16 xid;
	int index = get_cpu();

	max_sqes = BNX2FC_SCSI_MAX_SQES;
	/*
	 * NOTE: Free list insertions and deletions are protected with
	 * cmgr lock
	 */
	spin_lock_bh(&cmd_mgr->free_list_lock[index]);
	free_sqes = atomic_read(&tgt->free_sqes);
	if ((list_empty(&cmd_mgr->free_list[index])) ||
	    (tgt->num_active_ios.counter  >= max_sqes) ||
	    (free_sqes + max_sqes <= BNX2FC_SQ_WQES_MAX)) {
		spin_unlock_bh(&cmd_mgr->free_list_lock[index]);
		put_cpu();
		return NULL;
	}

	listp = (struct list_head *)
		cmd_mgr->free_list[index].next;
	list_del_init(listp);
	io_req = (struct bnx2fc_cmd *) listp;
	xid = io_req->xid;
	cmd_mgr->cmds[xid] = io_req;
	atomic_inc(&tgt->num_active_ios);
	atomic_dec(&tgt->free_sqes);
	spin_unlock_bh(&cmd_mgr->free_list_lock[index]);
	put_cpu();

	INIT_LIST_HEAD(&io_req->link);

	io_req->port = port;
	io_req->cmd_mgr = cmd_mgr;
	io_req->req_flags = 0;

	/* Bind io_bdt for this io_req */
	/* Have a static link between io_req and io_bdt_pool */
	bd_tbl = io_req->bd_tbl = cmd_mgr->io_bdt_pool[xid];
	bd_tbl->io_req = io_req;

	/* Hold the io_req  against deletion */
	kref_init(&io_req->refcount);
	return io_req;
}

void bnx2fc_cmd_release(struct kref *ref)
{
	struct bnx2fc_cmd *io_req = container_of(ref,
						struct bnx2fc_cmd, refcount);
	struct bnx2fc_cmd_mgr *cmd_mgr = io_req->cmd_mgr;
	int index;

	if (io_req->cmd_type == BNX2FC_SCSI_CMD)
		index = io_req->xid % num_possible_cpus();
	else
		index = RESERVE_FREE_LIST_INDEX;


	spin_lock_bh(&cmd_mgr->free_list_lock[index]);
	if (io_req->cmd_type != BNX2FC_SCSI_CMD)
		bnx2fc_free_mp_resc(io_req);
	cmd_mgr->cmds[io_req->xid] = NULL;
	/* Delete IO from retire queue */
	list_del_init(&io_req->link);
	/* Add it to the free list */
	list_add(&io_req->link,
			&cmd_mgr->free_list[index]);
	atomic_dec(&io_req->tgt->num_active_ios);
	spin_unlock_bh(&cmd_mgr->free_list_lock[index]);

}

static void bnx2fc_free_mp_resc(struct bnx2fc_cmd *io_req)
{
	struct bnx2fc_mp_req *mp_req = &(io_req->mp_req);
	struct bnx2fc_interface *interface = io_req->port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	size_t sz = sizeof(struct fcoe_bd_ctx);

	/* clear tm flags */
	mp_req->tm_flags = 0;
	if (mp_req->mp_req_bd) {
		dma_free_coherent(&hba->pcidev->dev, sz,
				     mp_req->mp_req_bd,
				     mp_req->mp_req_bd_dma);
		mp_req->mp_req_bd = NULL;
	}
	if (mp_req->mp_resp_bd) {
		dma_free_coherent(&hba->pcidev->dev, sz,
				     mp_req->mp_resp_bd,
				     mp_req->mp_resp_bd_dma);
		mp_req->mp_resp_bd = NULL;
	}
	if (mp_req->req_buf) {
		dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE,
				     mp_req->req_buf,
				     mp_req->req_buf_dma);
		mp_req->req_buf = NULL;
	}
	if (mp_req->resp_buf) {
		dma_free_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE,
				     mp_req->resp_buf,
				     mp_req->resp_buf_dma);
		mp_req->resp_buf = NULL;
	}
}

int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req)
{
	struct bnx2fc_mp_req *mp_req;
	struct fcoe_bd_ctx *mp_req_bd;
	struct fcoe_bd_ctx *mp_resp_bd;
	struct bnx2fc_interface *interface = io_req->port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	dma_addr_t addr;
	size_t sz;

	mp_req = (struct bnx2fc_mp_req *)&(io_req->mp_req);
	memset(mp_req, 0, sizeof(struct bnx2fc_mp_req));

	if (io_req->cmd_type != BNX2FC_ELS) {
		mp_req->req_len = sizeof(struct fcp_cmnd);
		io_req->data_xfer_len = mp_req->req_len;
	} else
		mp_req->req_len = io_req->data_xfer_len;

	mp_req->req_buf = dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE,
					     &mp_req->req_buf_dma,
					     GFP_ATOMIC);
	if (!mp_req->req_buf) {
		printk(KERN_ERR PFX "unable to alloc MP req buffer\n");
		bnx2fc_free_mp_resc(io_req);
		return FAILED;
	}

	mp_req->resp_buf = dma_alloc_coherent(&hba->pcidev->dev, CNIC_PAGE_SIZE,
					      &mp_req->resp_buf_dma,
					      GFP_ATOMIC);
	if (!mp_req->resp_buf) {
		printk(KERN_ERR PFX "unable to alloc TM resp buffer\n");
		bnx2fc_free_mp_resc(io_req);
		return FAILED;
	}
	memset(mp_req->req_buf, 0, CNIC_PAGE_SIZE);
	memset(mp_req->resp_buf, 0, CNIC_PAGE_SIZE);

	/* Allocate and map mp_req_bd and mp_resp_bd */
	sz = sizeof(struct fcoe_bd_ctx);
	mp_req->mp_req_bd = dma_alloc_coherent(&hba->pcidev->dev, sz,
						 &mp_req->mp_req_bd_dma,
						 GFP_ATOMIC);
	if (!mp_req->mp_req_bd) {
		printk(KERN_ERR PFX "unable to alloc MP req bd\n");
		bnx2fc_free_mp_resc(io_req);
		return FAILED;
	}
	mp_req->mp_resp_bd = dma_alloc_coherent(&hba->pcidev->dev, sz,
						 &mp_req->mp_resp_bd_dma,
						 GFP_ATOMIC);
	if (!mp_req->mp_resp_bd) {
		printk(KERN_ERR PFX "unable to alloc MP resp bd\n");
		bnx2fc_free_mp_resc(io_req);
		return FAILED;
	}
	/* Fill bd table */
	addr = mp_req->req_buf_dma;
	mp_req_bd = mp_req->mp_req_bd;
	mp_req_bd->buf_addr_lo = (u32)addr & 0xffffffff;
	mp_req_bd->buf_addr_hi = (u32)((u64)addr >> 32);
	mp_req_bd->buf_len = CNIC_PAGE_SIZE;
	mp_req_bd->flags = 0;

	/*
	 * MP buffer is either a task mgmt command or an ELS.
	 * So the assumption is that it consumes a single bd
	 * entry in the bd table
	 */
	mp_resp_bd = mp_req->mp_resp_bd;
	addr = mp_req->resp_buf_dma;
	mp_resp_bd->buf_addr_lo = (u32)addr & 0xffffffff;
	mp_resp_bd->buf_addr_hi = (u32)((u64)addr >> 32);
	mp_resp_bd->buf_len = CNIC_PAGE_SIZE;
	mp_resp_bd->flags = 0;

	return SUCCESS;
}

static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
{
	struct fc_lport *lport;
	struct fc_rport *rport;
	struct fc_rport_libfc_priv *rp;
	struct fcoe_port *port;
	struct bnx2fc_interface *interface;
	struct bnx2fc_rport *tgt;
	struct bnx2fc_cmd *io_req;
	struct bnx2fc_mp_req *tm_req;
	struct fcoe_task_ctx_entry *task;
	struct fcoe_task_ctx_entry *task_page;
	struct Scsi_Host *host = sc_cmd->device->host;
	struct fc_frame_header *fc_hdr;
	struct fcp_cmnd *fcp_cmnd;
	int task_idx, index;
	int rc = SUCCESS;
	u16 xid;
	u32 sid, did;
	unsigned long start = jiffies;

	lport = shost_priv(host);
	rport = starget_to_rport(scsi_target(sc_cmd->device));
	port = lport_priv(lport);
	interface = port->priv;

	if (rport == NULL) {
		printk(KERN_ERR PFX "device_reset: rport is NULL\n");
		rc = FAILED;
		goto tmf_err;
	}
	rp = rport->dd_data;

	rc = fc_block_scsi_eh(sc_cmd);
	if (rc)
		return rc;

	if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
		printk(KERN_ERR PFX "device_reset: link is not ready\n");
		rc = FAILED;
		goto tmf_err;
	}
	/* rport and tgt are allocated together, so tgt should be non-NULL */
	tgt = (struct bnx2fc_rport *)&rp[1];

	if (!(test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags))) {
		printk(KERN_ERR PFX "device_reset: tgt not offloaded\n");
		rc = FAILED;
		goto tmf_err;
	}
retry_tmf:
	io_req = bnx2fc_elstm_alloc(tgt, BNX2FC_TASK_MGMT_CMD);
	if (!io_req) {
		if (time_after(jiffies, start + HZ)) {
			printk(KERN_ERR PFX "tmf: Failed TMF");
			rc = FAILED;
			goto tmf_err;
		}
		msleep(20);
		goto retry_tmf;
	}
	/* Initialize rest of io_req fields */
	io_req->sc_cmd = sc_cmd;
	io_req->port = port;
	io_req->tgt = tgt;

	tm_req = (struct bnx2fc_mp_req *)&(io_req->mp_req);

	rc = bnx2fc_init_mp_req(io_req);
	if (rc == FAILED) {
		printk(KERN_ERR PFX "Task mgmt MP request init failed\n");
		spin_lock_bh(&tgt->tgt_lock);
		kref_put(&io_req->refcount, bnx2fc_cmd_release);
		spin_unlock_bh(&tgt->tgt_lock);
		goto tmf_err;
	}

	/* Set TM flags */
	io_req->io_req_flags = 0;
	tm_req->tm_flags = tm_flags;

	/* Fill FCP_CMND */
	bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)tm_req->req_buf);
	fcp_cmnd = (struct fcp_cmnd *)tm_req->req_buf;
	memset(fcp_cmnd->fc_cdb, 0,  sc_cmd->cmd_len);
	fcp_cmnd->fc_dl = 0;

	/* Fill FC header */
	fc_hdr = &(tm_req->req_fc_hdr);
	sid = tgt->sid;
	did = rport->port_id;
	__fc_fill_fc_hdr(fc_hdr, FC_RCTL_DD_UNSOL_CMD, did, sid,
			   FC_TYPE_FCP, FC_FC_FIRST_SEQ | FC_FC_END_SEQ |
			   FC_FC_SEQ_INIT, 0);
	/* Obtain exchange id */
	xid = io_req->xid;

	BNX2FC_TGT_DBG(tgt, "Initiate TMF - xid = 0x%x\n", xid);
	task_idx = xid/BNX2FC_TASKS_PER_PAGE;
	index = xid % BNX2FC_TASKS_PER_PAGE;

	/* Initialize task context for this IO request */
	task_page = (struct fcoe_task_ctx_entry *)
			interface->hba->task_ctx[task_idx];
	task = &(task_page[index]);
	bnx2fc_init_mp_task(io_req, task);

	sc_cmd->SCp.ptr = (char *)io_req;

	/* Obtain free SQ entry */
	spin_lock_bh(&tgt->tgt_lock);
	bnx2fc_add_2_sq(tgt, xid);

	/* Enqueue the io_req to active_tm_queue */
	io_req->on_tmf_queue = 1;
	list_add_tail(&io_req->link, &tgt->active_tm_queue);

	init_completion(&io_req->tm_done);
	io_req->wait_for_comp = 1;

	/* Ring doorbell */
	bnx2fc_ring_doorbell(tgt);
	spin_unlock_bh(&tgt->tgt_lock);

	rc = wait_for_completion_timeout(&io_req->tm_done,
					 interface->tm_timeout * HZ);
	spin_lock_bh(&tgt->tgt_lock);

	io_req->wait_for_comp = 0;
	if (!(test_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags))) {
		set_bit(BNX2FC_FLAG_TM_TIMEOUT, &io_req->req_flags);
		if (io_req->on_tmf_queue) {
			list_del_init(&io_req->link);
			io_req->on_tmf_queue = 0;
		}
		io_req->wait_for_comp = 1;
		bnx2fc_initiate_cleanup(io_req);
		spin_unlock_bh(&tgt->tgt_lock);
		rc = wait_for_completion_timeout(&io_req->tm_done,
						 BNX2FC_FW_TIMEOUT);
		spin_lock_bh(&tgt->tgt_lock);
		io_req->wait_for_comp = 0;
		if (!rc)
			kref_put(&io_req->refcount, bnx2fc_cmd_release);
	}

	spin_unlock_bh(&tgt->tgt_lock);

	if (!rc) {
		BNX2FC_TGT_DBG(tgt, "task mgmt command failed...\n");
		rc = FAILED;
	} else {
		BNX2FC_TGT_DBG(tgt, "task mgmt command success...\n");
		rc = SUCCESS;
	}
tmf_err:
	return rc;
}

int bnx2fc_initiate_abts(struct bnx2fc_cmd *io_req)
{
	struct fc_lport *lport;
	struct bnx2fc_rport *tgt = io_req->tgt;
	struct fc_rport *rport = tgt->rport;
	struct fc_rport_priv *rdata = tgt->rdata;
	struct bnx2fc_interface *interface;
	struct fcoe_port *port;
	struct bnx2fc_cmd *abts_io_req;
	struct fcoe_task_ctx_entry *task;
	struct fcoe_task_ctx_entry *task_page;
	struct fc_frame_header *fc_hdr;
	struct bnx2fc_mp_req *abts_req;
	int task_idx, index;
	u32 sid, did;
	u16 xid;
	int rc = SUCCESS;
	u32 r_a_tov = rdata->r_a_tov;

	/* called with tgt_lock held */
	BNX2FC_IO_DBG(io_req, "Entered bnx2fc_initiate_abts\n");

	port = io_req->port;
	interface = port->priv;
	lport = port->lport;

	if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) {
		printk(KERN_ERR PFX "initiate_abts: tgt not offloaded\n");
		rc = FAILED;
		goto abts_err;
	}

	if (rport == NULL) {
		printk(KERN_ERR PFX "initiate_abts: rport is NULL\n");
		rc = FAILED;
		goto abts_err;
	}

	if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
		printk(KERN_ERR PFX "initiate_abts: link is not ready\n");
		rc = FAILED;
		goto abts_err;
	}

	abts_io_req = bnx2fc_elstm_alloc(tgt, BNX2FC_ABTS);
	if (!abts_io_req) {
		printk(KERN_ERR PFX "abts: couldnt allocate cmd\n");
		rc = FAILED;
		goto abts_err;
	}

	/* Initialize rest of io_req fields */
	abts_io_req->sc_cmd = NULL;
	abts_io_req->port = port;
	abts_io_req->tgt = tgt;
	abts_io_req->data_xfer_len = 0; /* No data transfer for ABTS */

	abts_req = (struct bnx2fc_mp_req *)&(abts_io_req->mp_req);
	memset(abts_req, 0, sizeof(struct bnx2fc_mp_req));

	/* Fill FC header */
	fc_hdr = &(abts_req->req_fc_hdr);

	/* Obtain oxid and rxid for the original exchange to be aborted */
	fc_hdr->fh_ox_id = htons(io_req->xid);
	fc_hdr->fh_rx_id = htons(io_req->task->rxwr_txrd.var_ctx.rx_id);

	sid = tgt->sid;
	did = rport->port_id;

	__fc_fill_fc_hdr(fc_hdr, FC_RCTL_BA_ABTS, did, sid,
			   FC_TYPE_BLS, FC_FC_FIRST_SEQ | FC_FC_END_SEQ |
			   FC_FC_SEQ_INIT, 0);

	xid = abts_io_req->xid;
	BNX2FC_IO_DBG(abts_io_req, "ABTS io_req\n");
	task_idx = xid/BNX2FC_TASKS_PER_PAGE;
	index = xid % BNX2FC_TASKS_PER_PAGE;

	/* Initialize task context for this IO request */
	task_page = (struct fcoe_task_ctx_entry *)
			interface->hba->task_ctx[task_idx];
	task = &(task_page[index]);
	bnx2fc_init_mp_task(abts_io_req, task);

	/*
	 * ABTS task is a temporary task that will be cleaned up
	 * irrespective of ABTS response. We need to start the timer
	 * for the original exchange, as the CQE is posted for the original
	 * IO request.
	 *
	 * Timer for ABTS is started only when it is originated by a
	 * TM request. For the ABTS issued as part of ULP timeout,
	 * scsi-ml maintains the timers.
	 */

	/* if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags))*/
	bnx2fc_cmd_timer_set(io_req, 2 * r_a_tov);

	/* Obtain free SQ entry */
	bnx2fc_add_2_sq(tgt, xid);

	/* Ring doorbell */
	bnx2fc_ring_doorbell(tgt);

abts_err:
	return rc;
}

int bnx2fc_initiate_seq_cleanup(struct bnx2fc_cmd *orig_io_req, u32 offset,
				enum fc_rctl r_ctl)
{
	struct fc_lport *lport;
	struct bnx2fc_rport *tgt = orig_io_req->tgt;
	struct bnx2fc_interface *interface;
	struct fcoe_port *port;
	struct bnx2fc_cmd *seq_clnp_req;
	struct fcoe_task_ctx_entry *task;
	struct fcoe_task_ctx_entry *task_page;
	struct bnx2fc_els_cb_arg *cb_arg = NULL;
	int task_idx, index;
	u16 xid;
	int rc = 0;

	BNX2FC_IO_DBG(orig_io_req, "bnx2fc_initiate_seq_cleanup xid = 0x%x\n",
		   orig_io_req->xid);
	kref_get(&orig_io_req->refcount);

	port = orig_io_req->port;
	interface = port->priv;
	lport = port->lport;

	cb_arg = kzalloc(sizeof(struct bnx2fc_els_cb_arg), GFP_ATOMIC);
	if (!cb_arg) {
		printk(KERN_ERR PFX "Unable to alloc cb_arg for seq clnup\n");
		rc = -ENOMEM;
		goto cleanup_err;
	}

	seq_clnp_req = bnx2fc_elstm_alloc(tgt, BNX2FC_SEQ_CLEANUP);
	if (!seq_clnp_req) {
		printk(KERN_ERR PFX "cleanup: couldnt allocate cmd\n");
		rc = -ENOMEM;
		kfree(cb_arg);
		goto cleanup_err;
	}
	/* Initialize rest of io_req fields */
	seq_clnp_req->sc_cmd = NULL;
	seq_clnp_req->port = port;
	seq_clnp_req->tgt = tgt;
	seq_clnp_req->data_xfer_len = 0; /* No data transfer for cleanup */

	xid = seq_clnp_req->xid;

	task_idx = xid/BNX2FC_TASKS_PER_PAGE;
	index = xid % BNX2FC_TASKS_PER_PAGE;

	/* Initialize task context for this IO request */
	task_page = (struct fcoe_task_ctx_entry *)
		     interface->hba->task_ctx[task_idx];
	task = &(task_page[index]);
	cb_arg->aborted_io_req = orig_io_req;
	cb_arg->io_req = seq_clnp_req;
	cb_arg->r_ctl = r_ctl;
	cb_arg->offset = offset;
	seq_clnp_req->cb_arg = cb_arg;

	printk(KERN_ERR PFX "call init_seq_cleanup_task\n");
	bnx2fc_init_seq_cleanup_task(seq_clnp_req, task, orig_io_req, offset);

	/* Obtain free SQ entry */
	bnx2fc_add_2_sq(tgt, xid);

	/* Ring doorbell */
	bnx2fc_ring_doorbell(tgt);
cleanup_err:
	return rc;
}

int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req)
{
	struct fc_lport *lport;
	struct bnx2fc_rport *tgt = io_req->tgt;
	struct bnx2fc_interface *interface;
	struct fcoe_port *port;
	struct bnx2fc_cmd *cleanup_io_req;
	struct fcoe_task_ctx_entry *task;
	struct fcoe_task_ctx_entry *task_page;
	int task_idx, index;
	u16 xid, orig_xid;
	int rc = 0;

	/* ASSUMPTION: called with tgt_lock held */
	BNX2FC_IO_DBG(io_req, "Entered bnx2fc_initiate_cleanup\n");

	port = io_req->port;
	interface = port->priv;
	lport = port->lport;

	cleanup_io_req = bnx2fc_elstm_alloc(tgt, BNX2FC_CLEANUP);
	if (!cleanup_io_req) {
		printk(KERN_ERR PFX "cleanup: couldnt allocate cmd\n");
		rc = -1;
		goto cleanup_err;
	}

	/* Initialize rest of io_req fields */
	cleanup_io_req->sc_cmd = NULL;
	cleanup_io_req->port = port;
	cleanup_io_req->tgt = tgt;
	cleanup_io_req->data_xfer_len = 0; /* No data transfer for cleanup */

	xid = cleanup_io_req->xid;

	task_idx = xid/BNX2FC_TASKS_PER_PAGE;
	index = xid % BNX2FC_TASKS_PER_PAGE;

	/* Initialize task context for this IO request */
	task_page = (struct fcoe_task_ctx_entry *)
			interface->hba->task_ctx[task_idx];
	task = &(task_page[index]);
	orig_xid = io_req->xid;

	BNX2FC_IO_DBG(io_req, "CLEANUP io_req xid = 0x%x\n", xid);

	bnx2fc_init_cleanup_task(cleanup_io_req, task, orig_xid);

	/* Obtain free SQ entry */
	bnx2fc_add_2_sq(tgt, xid);

	/* Ring doorbell */
	bnx2fc_ring_doorbell(tgt);

cleanup_err:
	return rc;
}

/**
 * bnx2fc_eh_target_reset: Reset a target
 *
 * @sc_cmd:	SCSI command
 *
 * Set from SCSI host template to send task mgmt command to the target
 *	and wait for the response
 */
int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
{
	return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_TGT_RESET);
}

/**
 * bnx2fc_eh_device_reset - Reset a single LUN
 *
 * @sc_cmd:	SCSI command
 *
 * Set from SCSI host template to send task mgmt command to the target
 *	and wait for the response
 */
int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
{
	return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
}

int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
{
	struct bnx2fc_rport *tgt = io_req->tgt;
	int rc = SUCCESS;

	io_req->wait_for_comp = 1;
	bnx2fc_initiate_cleanup(io_req);

	spin_unlock_bh(&tgt->tgt_lock);

	wait_for_completion(&io_req->tm_done);

	io_req->wait_for_comp = 0;
	/*
	 * release the reference taken in eh_abort to allow the
	 * target to re-login after flushing IOs
	 */
	kref_put(&io_req->refcount, bnx2fc_cmd_release);

	spin_lock_bh(&tgt->tgt_lock);
	return rc;
}
/**
 * bnx2fc_eh_abort - eh_abort_handler api to abort an outstanding
 *			SCSI command
 *
 * @sc_cmd:	SCSI_ML command pointer
 *
 * SCSI abort request handler
 */
int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
{
	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
	struct fc_rport_libfc_priv *rp = rport->dd_data;
	struct bnx2fc_cmd *io_req;
	struct fc_lport *lport;
	struct bnx2fc_rport *tgt;
	int rc;

	rc = fc_block_scsi_eh(sc_cmd);
	if (rc)
		return rc;

	lport = shost_priv(sc_cmd->device->host);
	if ((lport->state != LPORT_ST_READY) || !(lport->link_up)) {
		printk(KERN_ERR PFX "eh_abort: link not ready\n");
		return FAILED;
	}

	tgt = (struct bnx2fc_rport *)&rp[1];

	BNX2FC_TGT_DBG(tgt, "Entered bnx2fc_eh_abort\n");

	spin_lock_bh(&tgt->tgt_lock);
	io_req = (struct bnx2fc_cmd *)sc_cmd->SCp.ptr;
	if (!io_req) {
		/* Command might have just completed */
		printk(KERN_ERR PFX "eh_abort: io_req is NULL\n");
		spin_unlock_bh(&tgt->tgt_lock);
		return SUCCESS;
	}
	BNX2FC_IO_DBG(io_req, "eh_abort - refcnt = %d\n",
		      io_req->refcount.refcount.counter);

	/* Hold IO request across abort processing */
	kref_get(&io_req->refcount);

	BUG_ON(tgt != io_req->tgt);

	/* Remove the io_req from the active_q. */
	/*
	 * Task Mgmt functions (LUN RESET & TGT RESET) will not
	 * issue an ABTS on this particular IO req, as the
	 * io_req is no longer in the active_q.
	 */
	if (tgt->flush_in_prog) {
		printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) "
			"flush in progress\n", io_req->xid);
		kref_put(&io_req->refcount, bnx2fc_cmd_release);
		spin_unlock_bh(&tgt->tgt_lock);
		return SUCCESS;
	}

	if (io_req->on_active_queue == 0) {
		printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) "
				"not on active_q\n", io_req->xid);
		/*
		 * This condition can happen only due to the FW bug,
		 * where we do not receive cleanup response from
		 * the FW. Handle this case gracefully by erroring
		 * back the IO request to SCSI-ml
		 */
		bnx2fc_scsi_done(io_req, DID_ABORT);

		kref_put(&io_req->refcount, bnx2fc_cmd_release);
		spin_unlock_bh(&tgt->tgt_lock);
		return SUCCESS;
	}

	/*
	 * Only eh_abort processing will remove the IO from
	 * active_cmd_q before processing the request. this is
	 * done to avoid race conditions between IOs aborted
	 * as part of task management completion and eh_abort
	 * processing
	 */
	list_del_init(&io_req->link);
	io_req->on_active_queue = 0;
	/* Move IO req to retire queue */
	list_add_tail(&io_req->link, &tgt->io_retire_queue);

	init_completion(&io_req->tm_done);

	if (test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags)) {
		printk(KERN_ERR PFX "eh_abort: io_req (xid = 0x%x) "
				"already in abts processing\n", io_req->xid);
		if (cancel_delayed_work(&io_req->timeout_work))
			kref_put(&io_req->refcount,
				 bnx2fc_cmd_release); /* drop timer hold */
		rc = bnx2fc_abts_cleanup(io_req);
		/* This only occurs when an task abort was requested while ABTS
		   is in progress.  Setting the IO_CLEANUP flag will skip the
		   RRQ process in the case when the fw generated SCSI_CMD cmpl
		   was a result from the ABTS request rather than the CLEANUP
		   request */
		set_bit(BNX2FC_FLAG_IO_CLEANUP,	&io_req->req_flags);
		goto out;
	}

	/* Cancel the current timer running on this io_req */
	if (cancel_delayed_work(&io_req->timeout_work))
		kref_put(&io_req->refcount,
			 bnx2fc_cmd_release); /* drop timer hold */
	set_bit(BNX2FC_FLAG_EH_ABORT, &io_req->req_flags);
	io_req->wait_for_comp = 1;
	rc = bnx2fc_initiate_abts(io_req);
	if (rc == FAILED) {
		bnx2fc_initiate_cleanup(io_req);
		spin_unlock_bh(&tgt->tgt_lock);
		wait_for_completion(&io_req->tm_done);
		spin_lock_bh(&tgt->tgt_lock);
		io_req->wait_for_comp = 0;
		goto done;
	}
	spin_unlock_bh(&tgt->tgt_lock);

	wait_for_completion(&io_req->tm_done);

	spin_lock_bh(&tgt->tgt_lock);
	io_req->wait_for_comp = 0;
	if (test_bit(BNX2FC_FLAG_IO_COMPL, &io_req->req_flags)) {
		BNX2FC_IO_DBG(io_req, "IO completed in a different context\n");
		rc = SUCCESS;
	} else if (!(test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
				      &io_req->req_flags))) {
		/* Let the scsi-ml try to recover this command */
		printk(KERN_ERR PFX "abort failed, xid = 0x%x\n",
		       io_req->xid);
		rc = bnx2fc_abts_cleanup(io_req);
		goto out;
	} else {
		/*
		 * We come here even when there was a race condition
		 * between timeout and abts completion, and abts
		 * completion happens just in time.
		 */
		BNX2FC_IO_DBG(io_req, "abort succeeded\n");
		rc = SUCCESS;
		bnx2fc_scsi_done(io_req, DID_ABORT);
		kref_put(&io_req->refcount, bnx2fc_cmd_release);
	}
done:
	/* release the reference taken in eh_abort */
	kref_put(&io_req->refcount, bnx2fc_cmd_release);
out:
	spin_unlock_bh(&tgt->tgt_lock);
	return rc;
}

void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnp_req,
				      struct fcoe_task_ctx_entry *task,
				      u8 rx_state)
{
	struct bnx2fc_els_cb_arg *cb_arg = seq_clnp_req->cb_arg;
	struct bnx2fc_cmd *orig_io_req = cb_arg->aborted_io_req;
	u32 offset = cb_arg->offset;
	enum fc_rctl r_ctl = cb_arg->r_ctl;
	int rc = 0;
	struct bnx2fc_rport *tgt = orig_io_req->tgt;

	BNX2FC_IO_DBG(orig_io_req, "Entered process_cleanup_compl xid = 0x%x"
			      "cmd_type = %d\n",
		   seq_clnp_req->xid, seq_clnp_req->cmd_type);

	if (rx_state == FCOE_TASK_RX_STATE_IGNORED_SEQUENCE_CLEANUP) {
		printk(KERN_ERR PFX "seq cleanup ignored - xid = 0x%x\n",
			seq_clnp_req->xid);
		goto free_cb_arg;
	}

	spin_unlock_bh(&tgt->tgt_lock);
	rc = bnx2fc_send_srr(orig_io_req, offset, r_ctl);
	spin_lock_bh(&tgt->tgt_lock);

	if (rc)
		printk(KERN_ERR PFX "clnup_compl: Unable to send SRR"
			" IO will abort\n");
	seq_clnp_req->cb_arg = NULL;
	kref_put(&orig_io_req->refcount, bnx2fc_cmd_release);
free_cb_arg:
	kfree(cb_arg);
	return;
}

void bnx2fc_process_cleanup_compl(struct bnx2fc_cmd *io_req,
				  struct fcoe_task_ctx_entry *task,
				  u8 num_rq)
{
	BNX2FC_IO_DBG(io_req, "Entered process_cleanup_compl "
			      "refcnt = %d, cmd_type = %d\n",
		   io_req->refcount.refcount.counter, io_req->cmd_type);
	bnx2fc_scsi_done(io_req, DID_ERROR);
	kref_put(&io_req->refcount, bnx2fc_cmd_release);
	if (io_req->wait_for_comp)
		complete(&io_req->tm_done);
}

void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req,
			       struct fcoe_task_ctx_entry *task,
			       u8 num_rq)
{
	u32 r_ctl;
	u32 r_a_tov = FC_DEF_R_A_TOV;
	u8 issue_rrq = 0;
	struct bnx2fc_rport *tgt = io_req->tgt;

	BNX2FC_IO_DBG(io_req, "Entered process_abts_compl xid = 0x%x"
			      "refcnt = %d, cmd_type = %d\n",
		   io_req->xid,
		   io_req->refcount.refcount.counter, io_req->cmd_type);

	if (test_and_set_bit(BNX2FC_FLAG_ABTS_DONE,
				       &io_req->req_flags)) {
		BNX2FC_IO_DBG(io_req, "Timer context finished processing"
				" this io\n");
		return;
	}

	/* Do not issue RRQ as this IO is already cleanedup */
	if (test_and_set_bit(BNX2FC_FLAG_IO_CLEANUP,
				&io_req->req_flags))
		goto io_compl;

	/*
	 * For ABTS issued due to SCSI eh_abort_handler, timeout
	 * values are maintained by scsi-ml itself. Cancel timeout
	 * in case ABTS issued as part of task management function
	 * or due to FW error.
	 */
	if (test_bit(BNX2FC_FLAG_ISSUE_ABTS, &io_req->req_flags))
		if (cancel_delayed_work(&io_req->timeout_work))
			kref_put(&io_req->refcount,
				 bnx2fc_cmd_release); /* drop timer hold */

	r_ctl = (u8)task->rxwr_only.union_ctx.comp_info.abts_rsp.r_ctl;

	switch (r_ctl) {
	case FC_RCTL_BA_ACC:
		/*
		 * Dont release this cmd yet. It will be relesed
		 * after we get RRQ response
		 */
		BNX2FC_IO_DBG(io_req, "ABTS response - ACC Send RRQ\n");
		issue_rrq = 1;
		break;

	case FC_RCTL_BA_RJT:
		BNX2FC_IO_DBG(io_req, "ABTS response - RJT\n");
		break;
	default:
		printk(KERN_ERR PFX "Unknown ABTS response\n");
		break;
	}

	if (issue_rrq) {
		BNX2FC_IO_DBG(io_req, "Issue RRQ after R_A_TOV\n");
		set_bit(BNX2FC_FLAG_ISSUE_RRQ, &io_req->req_flags);
	}
	set_bit(BNX2FC_FLAG_RETIRE_OXID, &io_req->req_flags);
	bnx2fc_cmd_timer_set(io_req, r_a_tov);

io_compl:
	if (io_req->wait_for_comp) {
		if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT,
				       &io_req->req_flags))
			complete(&io_req->tm_done);
	} else {
		/*
		 * We end up here when ABTS is issued as
		 * in asynchronous context, i.e., as part
		 * of task management completion, or
		 * when FW error is received or when the
		 * ABTS is issued when the IO is timed
		 * out.
		 */

		if (io_req->on_active_queue) {
			list_del_init(&io_req->link);
			io_req->on_active_queue = 0;
			/* Move IO req to retire queue */
			list_add_tail(&io_req->link, &tgt->io_retire_queue);
		}
		bnx2fc_scsi_done(io_req, DID_ERROR);
		kref_put(&io_req->refcount, bnx2fc_cmd_release);
	}
}

static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
{
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	struct bnx2fc_rport *tgt = io_req->tgt;
	struct bnx2fc_cmd *cmd, *tmp;
	u64 tm_lun = sc_cmd->device->lun;
	u64 lun;
	int rc = 0;

	/* called with tgt_lock held */
	BNX2FC_IO_DBG(io_req, "Entered bnx2fc_lun_reset_cmpl\n");
	/*
	 * Walk thru the active_ios queue and ABORT the IO
	 * that matches with the LUN that was reset
	 */
	list_for_each_entry_safe(cmd, tmp, &tgt->active_cmd_queue, link) {
		BNX2FC_TGT_DBG(tgt, "LUN RST cmpl: scan for pending IOs\n");
		lun = cmd->sc_cmd->device->lun;
		if (lun == tm_lun) {
			/* Initiate ABTS on this cmd */
			if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS,
					      &cmd->req_flags)) {
				/* cancel the IO timeout */
				if (cancel_delayed_work(&io_req->timeout_work))
					kref_put(&io_req->refcount,
						 bnx2fc_cmd_release);
							/* timer hold */
				rc = bnx2fc_initiate_abts(cmd);
				/* abts shouldn't fail in this context */
				WARN_ON(rc != SUCCESS);
			} else
				printk(KERN_ERR PFX "lun_rst: abts already in"
					" progress for this IO 0x%x\n",
					cmd->xid);
		}
	}
}

static void bnx2fc_tgt_reset_cmpl(struct bnx2fc_cmd *io_req)
{
	struct bnx2fc_rport *tgt = io_req->tgt;
	struct bnx2fc_cmd *cmd, *tmp;
	int rc = 0;

	/* called with tgt_lock held */
	BNX2FC_IO_DBG(io_req, "Entered bnx2fc_tgt_reset_cmpl\n");
	/*
	 * Walk thru the active_ios queue and ABORT the IO
	 * that matches with the LUN that was reset
	 */
	list_for_each_entry_safe(cmd, tmp, &tgt->active_cmd_queue, link) {
		BNX2FC_TGT_DBG(tgt, "TGT RST cmpl: scan for pending IOs\n");
		/* Initiate ABTS */
		if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS,
							&cmd->req_flags)) {
			/* cancel the IO timeout */
			if (cancel_delayed_work(&io_req->timeout_work))
				kref_put(&io_req->refcount,
					 bnx2fc_cmd_release); /* timer hold */
			rc = bnx2fc_initiate_abts(cmd);
			/* abts shouldn't fail in this context */
			WARN_ON(rc != SUCCESS);

		} else
			printk(KERN_ERR PFX "tgt_rst: abts already in progress"
				" for this IO 0x%x\n", cmd->xid);
	}
}

void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
			     struct fcoe_task_ctx_entry *task, u8 num_rq)
{
	struct bnx2fc_mp_req *tm_req;
	struct fc_frame_header *fc_hdr;
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	u64 *hdr;
	u64 *temp_hdr;
	void *rsp_buf;

	/* Called with tgt_lock held */
	BNX2FC_IO_DBG(io_req, "Entered process_tm_compl\n");

	if (!(test_bit(BNX2FC_FLAG_TM_TIMEOUT, &io_req->req_flags)))
		set_bit(BNX2FC_FLAG_TM_COMPL, &io_req->req_flags);
	else {
		/* TM has already timed out and we got
		 * delayed completion. Ignore completion
		 * processing.
		 */
		return;
	}

	tm_req = &(io_req->mp_req);
	fc_hdr = &(tm_req->resp_fc_hdr);
	hdr = (u64 *)fc_hdr;
	temp_hdr = (u64 *)
		&task->rxwr_only.union_ctx.comp_info.mp_rsp.fc_hdr;
	hdr[0] = cpu_to_be64(temp_hdr[0]);
	hdr[1] = cpu_to_be64(temp_hdr[1]);
	hdr[2] = cpu_to_be64(temp_hdr[2]);

	tm_req->resp_len =
		task->rxwr_only.union_ctx.comp_info.mp_rsp.mp_payload_len;

	rsp_buf = tm_req->resp_buf;

	if (fc_hdr->fh_r_ctl == FC_RCTL_DD_CMD_STATUS) {
		bnx2fc_parse_fcp_rsp(io_req,
				     (struct fcoe_fcp_rsp_payload *)
				     rsp_buf, num_rq);
		if (io_req->fcp_rsp_code == 0) {
			/* TM successful */
			if (tm_req->tm_flags & FCP_TMF_LUN_RESET)
				bnx2fc_lun_reset_cmpl(io_req);
			else if (tm_req->tm_flags & FCP_TMF_TGT_RESET)
				bnx2fc_tgt_reset_cmpl(io_req);
		}
	} else {
		printk(KERN_ERR PFX "tmf's fc_hdr r_ctl = 0x%x\n",
			fc_hdr->fh_r_ctl);
	}
	if (!sc_cmd->SCp.ptr) {
		printk(KERN_ERR PFX "tm_compl: SCp.ptr is NULL\n");
		return;
	}
	switch (io_req->fcp_status) {
	case FC_GOOD:
		if (io_req->cdb_status == 0) {
			/* Good IO completion */
			sc_cmd->result = DID_OK << 16;
		} else {
			/* Transport status is good, SCSI status not good */
			sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;
		}
		if (io_req->fcp_resid)
			scsi_set_resid(sc_cmd, io_req->fcp_resid);
		break;

	default:
		BNX2FC_IO_DBG(io_req, "process_tm_compl: fcp_status = %d\n",
			   io_req->fcp_status);
		break;
	}

	sc_cmd = io_req->sc_cmd;
	io_req->sc_cmd = NULL;

	/* check if the io_req exists in tgt's tmf_q */
	if (io_req->on_tmf_queue) {

		list_del_init(&io_req->link);
		io_req->on_tmf_queue = 0;
	} else {

		printk(KERN_ERR PFX "Command not on active_cmd_queue!\n");
		return;
	}

	sc_cmd->SCp.ptr = NULL;
	sc_cmd->scsi_done(sc_cmd);

	kref_put(&io_req->refcount, bnx2fc_cmd_release);
	if (io_req->wait_for_comp) {
		BNX2FC_IO_DBG(io_req, "tm_compl - wake up the waiter\n");
		complete(&io_req->tm_done);
	}
}

static int bnx2fc_split_bd(struct bnx2fc_cmd *io_req, u64 addr, int sg_len,
			   int bd_index)
{
	struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl;
	int frag_size, sg_frags;

	sg_frags = 0;
	while (sg_len) {
		if (sg_len >= BNX2FC_BD_SPLIT_SZ)
			frag_size = BNX2FC_BD_SPLIT_SZ;
		else
			frag_size = sg_len;
		bd[bd_index + sg_frags].buf_addr_lo = addr & 0xffffffff;
		bd[bd_index + sg_frags].buf_addr_hi  = addr >> 32;
		bd[bd_index + sg_frags].buf_len = (u16)frag_size;
		bd[bd_index + sg_frags].flags = 0;

		addr += (u64) frag_size;
		sg_frags++;
		sg_len -= frag_size;
	}
	return sg_frags;

}

static int bnx2fc_map_sg(struct bnx2fc_cmd *io_req)
{
	struct bnx2fc_interface *interface = io_req->port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	struct scsi_cmnd *sc = io_req->sc_cmd;
	struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl;
	struct scatterlist *sg;
	int byte_count = 0;
	int sg_count = 0;
	int bd_count = 0;
	int sg_frags;
	unsigned int sg_len;
	u64 addr;
	int i;

	/*
	 * Use dma_map_sg directly to ensure we're using the correct
	 * dev struct off of pcidev.
	 */
	sg_count = dma_map_sg(&hba->pcidev->dev, scsi_sglist(sc),
			      scsi_sg_count(sc), sc->sc_data_direction);
	scsi_for_each_sg(sc, sg, sg_count, i) {
		sg_len = sg_dma_len(sg);
		addr = sg_dma_address(sg);
		if (sg_len > BNX2FC_MAX_BD_LEN) {
			sg_frags = bnx2fc_split_bd(io_req, addr, sg_len,
						   bd_count);
		} else {

			sg_frags = 1;
			bd[bd_count].buf_addr_lo = addr & 0xffffffff;
			bd[bd_count].buf_addr_hi  = addr >> 32;
			bd[bd_count].buf_len = (u16)sg_len;
			bd[bd_count].flags = 0;
		}
		bd_count += sg_frags;
		byte_count += sg_len;
	}
	if (byte_count != scsi_bufflen(sc))
		printk(KERN_ERR PFX "byte_count = %d != scsi_bufflen = %d, "
			"task_id = 0x%x\n", byte_count, scsi_bufflen(sc),
			io_req->xid);
	return bd_count;
}

static int bnx2fc_build_bd_list_from_sg(struct bnx2fc_cmd *io_req)
{
	struct scsi_cmnd *sc = io_req->sc_cmd;
	struct fcoe_bd_ctx *bd = io_req->bd_tbl->bd_tbl;
	int bd_count;

	if (scsi_sg_count(sc)) {
		bd_count = bnx2fc_map_sg(io_req);
		if (bd_count == 0)
			return -ENOMEM;
	} else {
		bd_count = 0;
		bd[0].buf_addr_lo = bd[0].buf_addr_hi = 0;
		bd[0].buf_len = bd[0].flags = 0;
	}
	io_req->bd_tbl->bd_valid = bd_count;

	return 0;
}

static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req)
{
	struct scsi_cmnd *sc = io_req->sc_cmd;
	struct bnx2fc_interface *interface = io_req->port->priv;
	struct bnx2fc_hba *hba = interface->hba;

	/*
	 * Use dma_unmap_sg directly to ensure we're using the correct
	 * dev struct off of pcidev.
	 */
	if (io_req->bd_tbl->bd_valid && sc && scsi_sg_count(sc)) {
		dma_unmap_sg(&hba->pcidev->dev, scsi_sglist(sc),
		    scsi_sg_count(sc), sc->sc_data_direction);
		io_req->bd_tbl->bd_valid = 0;
	}
}

void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req,
				  struct fcp_cmnd *fcp_cmnd)
{
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;

	memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd));

	int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);

	fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len);
	memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);

	fcp_cmnd->fc_cmdref = 0;
	fcp_cmnd->fc_pri_ta = 0;
	fcp_cmnd->fc_tm_flags = io_req->mp_req.tm_flags;
	fcp_cmnd->fc_flags = io_req->io_req_flags;
	fcp_cmnd->fc_pri_ta = FCP_PTA_SIMPLE;
}

static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req,
				 struct fcoe_fcp_rsp_payload *fcp_rsp,
				 u8 num_rq)
{
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	struct bnx2fc_rport *tgt = io_req->tgt;
	u8 rsp_flags = fcp_rsp->fcp_flags.flags;
	u32 rq_buff_len = 0;
	int i;
	unsigned char *rq_data;
	unsigned char *dummy;
	int fcp_sns_len = 0;
	int fcp_rsp_len = 0;

	io_req->fcp_status = FC_GOOD;
	io_req->fcp_resid = 0;
	if (rsp_flags & (FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER |
	    FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER))
		io_req->fcp_resid = fcp_rsp->fcp_resid;

	io_req->scsi_comp_flags = rsp_flags;
	CMD_SCSI_STATUS(sc_cmd) = io_req->cdb_status =
				fcp_rsp->scsi_status_code;

	/* Fetch fcp_rsp_info and fcp_sns_info if available */
	if (num_rq) {

		/*
		 * We do not anticipate num_rq >1, as the linux defined
		 * SCSI_SENSE_BUFFERSIZE is 96 bytes + 8 bytes of FCP_RSP_INFO
		 * 256 bytes of single rq buffer is good enough to hold this.
		 */

		if (rsp_flags &
		    FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID) {
			fcp_rsp_len = rq_buff_len
					= fcp_rsp->fcp_rsp_len;
		}

		if (rsp_flags &
		    FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID) {
			fcp_sns_len = fcp_rsp->fcp_sns_len;
			rq_buff_len += fcp_rsp->fcp_sns_len;
		}

		io_req->fcp_rsp_len = fcp_rsp_len;
		io_req->fcp_sns_len = fcp_sns_len;

		if (rq_buff_len > num_rq * BNX2FC_RQ_BUF_SZ) {
			/* Invalid sense sense length. */
			printk(KERN_ERR PFX "invalid sns length %d\n",
				rq_buff_len);
			/* reset rq_buff_len */
			rq_buff_len =  num_rq * BNX2FC_RQ_BUF_SZ;
		}

		rq_data = bnx2fc_get_next_rqe(tgt, 1);

		if (num_rq > 1) {
			/* We do not need extra sense data */
			for (i = 1; i < num_rq; i++)
				dummy = bnx2fc_get_next_rqe(tgt, 1);
		}

		/* fetch fcp_rsp_code */
		if ((fcp_rsp_len == 4) || (fcp_rsp_len == 8)) {
			/* Only for task management function */
			io_req->fcp_rsp_code = rq_data[3];
			printk(KERN_ERR PFX "fcp_rsp_code = %d\n",
				io_req->fcp_rsp_code);
		}

		/* fetch sense data */
		rq_data += fcp_rsp_len;

		if (fcp_sns_len > SCSI_SENSE_BUFFERSIZE) {
			printk(KERN_ERR PFX "Truncating sense buffer\n");
			fcp_sns_len = SCSI_SENSE_BUFFERSIZE;
		}

		memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
		if (fcp_sns_len)
			memcpy(sc_cmd->sense_buffer, rq_data, fcp_sns_len);

		/* return RQ entries */
		for (i = 0; i < num_rq; i++)
			bnx2fc_return_rqe(tgt, 1);
	}
}

/**
 * bnx2fc_queuecommand - Queuecommand function of the scsi template
 *
 * @host:	The Scsi_Host the command was issued to
 * @sc_cmd:	struct scsi_cmnd to be executed
 *
 * This is the IO strategy routine, called by SCSI-ML
 **/
int bnx2fc_queuecommand(struct Scsi_Host *host,
			struct scsi_cmnd *sc_cmd)
{
	struct fc_lport *lport = shost_priv(host);
	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
	struct fc_rport_libfc_priv *rp = rport->dd_data;
	struct bnx2fc_rport *tgt;
	struct bnx2fc_cmd *io_req;
	int rc = 0;
	int rval;

	rval = fc_remote_port_chkready(rport);
	if (rval) {
		sc_cmd->result = rval;
		sc_cmd->scsi_done(sc_cmd);
		return 0;
	}

	if ((lport->state != LPORT_ST_READY) || !(lport->link_up)) {
		rc = SCSI_MLQUEUE_HOST_BUSY;
		goto exit_qcmd;
	}

	/* rport and tgt are allocated together, so tgt should be non-NULL */
	tgt = (struct bnx2fc_rport *)&rp[1];

	if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) {
		/*
		 * Session is not offloaded yet. Let SCSI-ml retry
		 * the command.
		 */
		rc = SCSI_MLQUEUE_TARGET_BUSY;
		goto exit_qcmd;
	}
	if (tgt->retry_delay_timestamp) {
		if (time_after(jiffies, tgt->retry_delay_timestamp)) {
			tgt->retry_delay_timestamp = 0;
		} else {
			/* If retry_delay timer is active, flow off the ML */
			rc = SCSI_MLQUEUE_TARGET_BUSY;
			goto exit_qcmd;
		}
	}

	spin_lock_bh(&tgt->tgt_lock);

	io_req = bnx2fc_cmd_alloc(tgt);
	if (!io_req) {
		rc = SCSI_MLQUEUE_HOST_BUSY;
		goto exit_qcmd_tgtlock;
	}
	io_req->sc_cmd = sc_cmd;

	if (bnx2fc_post_io_req(tgt, io_req)) {
		printk(KERN_ERR PFX "Unable to post io_req\n");
		rc = SCSI_MLQUEUE_HOST_BUSY;
		goto exit_qcmd_tgtlock;
	}

exit_qcmd_tgtlock:
	spin_unlock_bh(&tgt->tgt_lock);
exit_qcmd:
	return rc;
}

void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
				   struct fcoe_task_ctx_entry *task,
				   u8 num_rq)
{
	struct fcoe_fcp_rsp_payload *fcp_rsp;
	struct bnx2fc_rport *tgt = io_req->tgt;
	struct scsi_cmnd *sc_cmd;
	struct Scsi_Host *host;


	/* scsi_cmd_cmpl is called with tgt lock held */

	if (test_and_set_bit(BNX2FC_FLAG_IO_COMPL, &io_req->req_flags)) {
		/* we will not receive ABTS response for this IO */
		BNX2FC_IO_DBG(io_req, "Timer context finished processing "
			   "this scsi cmd\n");
	}

	/* Cancel the timeout_work, as we received IO completion */
	if (cancel_delayed_work(&io_req->timeout_work))
		kref_put(&io_req->refcount,
			 bnx2fc_cmd_release); /* drop timer hold */

	sc_cmd = io_req->sc_cmd;
	if (sc_cmd == NULL) {
		printk(KERN_ERR PFX "scsi_cmd_compl - sc_cmd is NULL\n");
		return;
	}

	/* Fetch fcp_rsp from task context and perform cmd completion */
	fcp_rsp = (struct fcoe_fcp_rsp_payload *)
		   &(task->rxwr_only.union_ctx.comp_info.fcp_rsp.payload);

	/* parse fcp_rsp and obtain sense data from RQ if available */
	bnx2fc_parse_fcp_rsp(io_req, fcp_rsp, num_rq);

	host = sc_cmd->device->host;
	if (!sc_cmd->SCp.ptr) {
		printk(KERN_ERR PFX "SCp.ptr is NULL\n");
		return;
	}

	if (io_req->on_active_queue) {
		list_del_init(&io_req->link);
		io_req->on_active_queue = 0;
		/* Move IO req to retire queue */
		list_add_tail(&io_req->link, &tgt->io_retire_queue);
	} else {
		/* This should not happen, but could have been pulled
		 * by bnx2fc_flush_active_ios(), or during a race
		 * between command abort and (late) completion.
		 */
		BNX2FC_IO_DBG(io_req, "xid not on active_cmd_queue\n");
		if (io_req->wait_for_comp)
			if (test_and_clear_bit(BNX2FC_FLAG_EH_ABORT,
					       &io_req->req_flags))
				complete(&io_req->tm_done);
	}

	bnx2fc_unmap_sg_list(io_req);
	io_req->sc_cmd = NULL;

	switch (io_req->fcp_status) {
	case FC_GOOD:
		if (io_req->cdb_status == 0) {
			/* Good IO completion */
			sc_cmd->result = DID_OK << 16;
		} else {
			/* Transport status is good, SCSI status not good */
			BNX2FC_IO_DBG(io_req, "scsi_cmpl: cdb_status = %d"
				 " fcp_resid = 0x%x\n",
				io_req->cdb_status, io_req->fcp_resid);
			sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;

			if (io_req->cdb_status == SAM_STAT_TASK_SET_FULL ||
			    io_req->cdb_status == SAM_STAT_BUSY) {
				/* Set the jiffies + retry_delay_timer * 100ms
				   for the rport/tgt */
				tgt->retry_delay_timestamp = jiffies +
					fcp_rsp->retry_delay_timer * HZ / 10;
			}

		}
		if (io_req->fcp_resid)
			scsi_set_resid(sc_cmd, io_req->fcp_resid);
		break;
	default:
		printk(KERN_ERR PFX "scsi_cmd_compl: fcp_status = %d\n",
			io_req->fcp_status);
		break;
	}
	sc_cmd->SCp.ptr = NULL;
	sc_cmd->scsi_done(sc_cmd);
	kref_put(&io_req->refcount, bnx2fc_cmd_release);
}

int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
			       struct bnx2fc_cmd *io_req)
{
	struct fcoe_task_ctx_entry *task;
	struct fcoe_task_ctx_entry *task_page;
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	struct fcoe_port *port = tgt->port;
	struct bnx2fc_interface *interface = port->priv;
	struct bnx2fc_hba *hba = interface->hba;
	struct fc_lport *lport = port->lport;
	struct fc_stats *stats;
	int task_idx, index;
	u16 xid;

	/* bnx2fc_post_io_req() is called with the tgt_lock held */

	/* Initialize rest of io_req fields */
	io_req->cmd_type = BNX2FC_SCSI_CMD;
	io_req->port = port;
	io_req->tgt = tgt;
	io_req->data_xfer_len = scsi_bufflen(sc_cmd);
	sc_cmd->SCp.ptr = (char *)io_req;

	stats = per_cpu_ptr(lport->stats, get_cpu());
	if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
		io_req->io_req_flags = BNX2FC_READ;
		stats->InputRequests++;
		stats->InputBytes += io_req->data_xfer_len;
	} else if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
		io_req->io_req_flags = BNX2FC_WRITE;
		stats->OutputRequests++;
		stats->OutputBytes += io_req->data_xfer_len;
	} else {
		io_req->io_req_flags = 0;
		stats->ControlRequests++;
	}
	put_cpu();

	xid = io_req->xid;

	/* Build buffer descriptor list for firmware from sg list */
	if (bnx2fc_build_bd_list_from_sg(io_req)) {
		printk(KERN_ERR PFX "BD list creation failed\n");
		kref_put(&io_req->refcount, bnx2fc_cmd_release);
		return -EAGAIN;
	}

	task_idx = xid / BNX2FC_TASKS_PER_PAGE;
	index = xid % BNX2FC_TASKS_PER_PAGE;

	/* Initialize task context for this IO request */
	task_page = (struct fcoe_task_ctx_entry *) hba->task_ctx[task_idx];
	task = &(task_page[index]);
	bnx2fc_init_task(io_req, task);

	if (tgt->flush_in_prog) {
		printk(KERN_ERR PFX "Flush in progress..Host Busy\n");
		kref_put(&io_req->refcount, bnx2fc_cmd_release);
		return -EAGAIN;
	}

	if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) {
		printk(KERN_ERR PFX "Session not ready...post_io\n");
		kref_put(&io_req->refcount, bnx2fc_cmd_release);
		return -EAGAIN;
	}

	/* Time IO req */
	if (tgt->io_timeout)
		bnx2fc_cmd_timer_set(io_req, BNX2FC_IO_TIMEOUT);
	/* Obtain free SQ entry */
	bnx2fc_add_2_sq(tgt, xid);

	/* Enqueue the io_req to active_cmd_queue */

	io_req->on_active_queue = 1;
	/* move io_req from pending_queue to active_queue */
	list_add_tail(&io_req->link, &tgt->active_cmd_queue);

	/* Ring doorbell */
	bnx2fc_ring_doorbell(tgt);
	return 0;
}
