// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Broadcom. All Rights Reserved. The term
 * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries.
 */

#include "efct_driver.h"
#include "efct_hw.h"

#define enable_tsend_auto_resp(efct)	1
#define enable_treceive_auto_resp(efct)	0

#define SCSI_IOFMT "[%04x][i:%04x t:%04x h:%04x]"

#define scsi_io_printf(io, fmt, ...) \
	efc_log_debug(io->efct, "[%s]" SCSI_IOFMT fmt, \
		io->node->display_name, io->instance_index,\
		io->init_task_tag, io->tgt_task_tag, io->hw_tag, ##__VA_ARGS__)

#define EFCT_LOG_ENABLE_SCSI_TRACE(efct)                \
		(((efct) != NULL) ? (((efct)->logmask & (1U << 2)) != 0) : 0)

#define scsi_io_trace(io, fmt, ...) \
	do { \
		if (EFCT_LOG_ENABLE_SCSI_TRACE(io->efct)) \
			scsi_io_printf(io, fmt, ##__VA_ARGS__); \
	} while (0)

struct efct_io *
efct_scsi_io_alloc(struct efct_node *node)
{
	struct efct *efct;
	struct efct_xport *xport;
	struct efct_io *io;
	unsigned long flags;

	efct = node->efct;

	xport = efct->xport;

	io = efct_io_pool_io_alloc(efct->xport->io_pool);
	if (!io) {
		efc_log_err(efct, "IO alloc Failed\n");
		atomic_add_return(1, &xport->io_alloc_failed_count);
		return NULL;
	}

	/* initialize refcount */
	kref_init(&io->ref);
	io->release = _efct_scsi_io_free;

	/* set generic fields */
	io->efct = efct;
	io->node = node;
	kref_get(&node->ref);

	/* set type and name */
	io->io_type = EFCT_IO_TYPE_IO;
	io->display_name = "scsi_io";

	io->cmd_ini = false;
	io->cmd_tgt = true;

	/* Add to node's active_ios list */
	INIT_LIST_HEAD(&io->list_entry);
	spin_lock_irqsave(&node->active_ios_lock, flags);
	list_add(&io->list_entry, &node->active_ios);

	spin_unlock_irqrestore(&node->active_ios_lock, flags);

	return io;
}

void
_efct_scsi_io_free(struct kref *arg)
{
	struct efct_io *io = container_of(arg, struct efct_io, ref);
	struct efct *efct = io->efct;
	struct efct_node *node = io->node;
	unsigned long flags = 0;

	scsi_io_trace(io, "freeing io 0x%p %s\n", io, io->display_name);

	if (io->io_free) {
		efc_log_err(efct, "IO already freed.\n");
		return;
	}

	spin_lock_irqsave(&node->active_ios_lock, flags);
	list_del_init(&io->list_entry);
	spin_unlock_irqrestore(&node->active_ios_lock, flags);

	kref_put(&node->ref, node->release);
	io->node = NULL;
	efct_io_pool_io_free(efct->xport->io_pool, io);
}

void
efct_scsi_io_free(struct efct_io *io)
{
	scsi_io_trace(io, "freeing io 0x%p %s\n", io, io->display_name);
	WARN_ON(!refcount_read(&io->ref.refcount));
	kref_put(&io->ref, io->release);
}

static void
efct_target_io_cb(struct efct_hw_io *hio, u32 length, int status,
		  u32 ext_status, void *app)
{
	u32 flags = 0;
	struct efct_io *io = app;
	struct efct *efct;
	enum efct_scsi_io_status scsi_stat = EFCT_SCSI_STATUS_GOOD;
	efct_scsi_io_cb_t cb;

	if (!io || !io->efct) {
		pr_err("%s: IO can not be NULL\n", __func__);
		return;
	}

	scsi_io_trace(io, "status x%x ext_status x%x\n", status, ext_status);

	efct = io->efct;

	io->transferred += length;

	if (!io->scsi_tgt_cb) {
		efct_scsi_check_pending(efct);
		return;
	}

	/* Call target server completion */
	cb = io->scsi_tgt_cb;

	/* Clear the callback before invoking the callback */
	io->scsi_tgt_cb = NULL;

	/* if status was good, and auto-good-response was set,
	 * then callback target-server with IO_CMPL_RSP_SENT,
	 * otherwise send IO_CMPL
	 */
	if (status == 0 && io->auto_resp)
		flags |= EFCT_SCSI_IO_CMPL_RSP_SENT;
	else
		flags |= EFCT_SCSI_IO_CMPL;

	switch (status) {
	case SLI4_FC_WCQE_STATUS_SUCCESS:
		scsi_stat = EFCT_SCSI_STATUS_GOOD;
		break;
	case SLI4_FC_WCQE_STATUS_DI_ERROR:
		if (ext_status & SLI4_FC_DI_ERROR_GE)
			scsi_stat = EFCT_SCSI_STATUS_DIF_GUARD_ERR;
		else if (ext_status & SLI4_FC_DI_ERROR_AE)
			scsi_stat = EFCT_SCSI_STATUS_DIF_APP_TAG_ERROR;
		else if (ext_status & SLI4_FC_DI_ERROR_RE)
			scsi_stat = EFCT_SCSI_STATUS_DIF_REF_TAG_ERROR;
		else
			scsi_stat = EFCT_SCSI_STATUS_DIF_UNKNOWN_ERROR;
		break;
	case SLI4_FC_WCQE_STATUS_LOCAL_REJECT:
		switch (ext_status) {
		case SLI4_FC_LOCAL_REJECT_INVALID_RELOFFSET:
		case SLI4_FC_LOCAL_REJECT_ABORT_REQUESTED:
			scsi_stat = EFCT_SCSI_STATUS_ABORTED;
			break;
		case SLI4_FC_LOCAL_REJECT_INVALID_RPI:
			scsi_stat = EFCT_SCSI_STATUS_NEXUS_LOST;
			break;
		case SLI4_FC_LOCAL_REJECT_NO_XRI:
			scsi_stat = EFCT_SCSI_STATUS_NO_IO;
			break;
		default:
			/*we have seen 0x0d(TX_DMA_FAILED err)*/
			scsi_stat = EFCT_SCSI_STATUS_ERROR;
			break;
		}
		break;

	case SLI4_FC_WCQE_STATUS_TARGET_WQE_TIMEOUT:
		/* target IO timed out */
		scsi_stat = EFCT_SCSI_STATUS_TIMEDOUT_AND_ABORTED;
		break;

	case SLI4_FC_WCQE_STATUS_SHUTDOWN:
		/* Target IO cancelled by HW */
		scsi_stat = EFCT_SCSI_STATUS_SHUTDOWN;
		break;

	default:
		scsi_stat = EFCT_SCSI_STATUS_ERROR;
		break;
	}

	cb(io, scsi_stat, flags, io->scsi_tgt_cb_arg);

	efct_scsi_check_pending(efct);
}

static int
efct_scsi_build_sgls(struct efct_hw *hw, struct efct_hw_io *hio,
		     struct efct_scsi_sgl *sgl, u32 sgl_count,
		     enum efct_hw_io_type type)
{
	int rc;
	u32 i;
	struct efct *efct = hw->os;

	/* Initialize HW SGL */
	rc = efct_hw_io_init_sges(hw, hio, type);
	if (rc) {
		efc_log_err(efct, "efct_hw_io_init_sges failed: %d\n", rc);
		return -EIO;
	}

	for (i = 0; i < sgl_count; i++) {
		/* Add data SGE */
		rc = efct_hw_io_add_sge(hw, hio, sgl[i].addr, sgl[i].len);
		if (rc) {
			efc_log_err(efct, "add sge failed cnt=%d rc=%d\n",
				    sgl_count, rc);
			return rc;
		}
	}

	return 0;
}

static void efc_log_sgl(struct efct_io *io)
{
	struct efct_hw_io *hio = io->hio;
	struct sli4_sge *data = NULL;
	u32 *dword = NULL;
	u32 i;
	u32 n_sge;

	scsi_io_trace(io, "def_sgl at 0x%x 0x%08x\n",
		      upper_32_bits(hio->def_sgl.phys),
		      lower_32_bits(hio->def_sgl.phys));
	n_sge = (hio->sgl == &hio->def_sgl) ? hio->n_sge : hio->def_sgl_count;
	for (i = 0, data = hio->def_sgl.virt; i < n_sge; i++, data++) {
		dword = (u32 *)data;

		scsi_io_trace(io, "SGL %2d 0x%08x 0x%08x 0x%08x 0x%08x\n",
			      i, dword[0], dword[1], dword[2], dword[3]);

		if (dword[2] & (1U << 31))
			break;
	}
}

static void
efct_scsi_check_pending_async_cb(struct efct_hw *hw, int status,
				 u8 *mqe, void *arg)
{
	struct efct_io *io = arg;

	if (io) {
		efct_hw_done_t cb = io->hw_cb;

		if (!io->hw_cb)
			return;

		io->hw_cb = NULL;
		(cb)(io->hio, 0, SLI4_FC_WCQE_STATUS_DISPATCH_ERROR, 0, io);
	}
}

static int
efct_scsi_io_dispatch_hw_io(struct efct_io *io, struct efct_hw_io *hio)
{
	int rc = 0;
	struct efct *efct = io->efct;

	/* Got a HW IO;
	 * update ini/tgt_task_tag with HW IO info and dispatch
	 */
	io->hio = hio;
	if (io->cmd_tgt)
		io->tgt_task_tag = hio->indicator;
	else if (io->cmd_ini)
		io->init_task_tag = hio->indicator;
	io->hw_tag = hio->reqtag;

	hio->eq = io->hw_priv;

	/* Copy WQ steering */
	switch (io->wq_steering) {
	case EFCT_SCSI_WQ_STEERING_CLASS >> EFCT_SCSI_WQ_STEERING_SHIFT:
		hio->wq_steering = EFCT_HW_WQ_STEERING_CLASS;
		break;
	case EFCT_SCSI_WQ_STEERING_REQUEST >> EFCT_SCSI_WQ_STEERING_SHIFT:
		hio->wq_steering = EFCT_HW_WQ_STEERING_REQUEST;
		break;
	case EFCT_SCSI_WQ_STEERING_CPU >> EFCT_SCSI_WQ_STEERING_SHIFT:
		hio->wq_steering = EFCT_HW_WQ_STEERING_CPU;
		break;
	}

	switch (io->io_type) {
	case EFCT_IO_TYPE_IO:
		rc = efct_scsi_build_sgls(&efct->hw, io->hio,
					  io->sgl, io->sgl_count, io->hio_type);
		if (rc)
			break;

		if (EFCT_LOG_ENABLE_SCSI_TRACE(efct))
			efc_log_sgl(io);

		if (io->app_id)
			io->iparam.fcp_tgt.app_id = io->app_id;

		io->iparam.fcp_tgt.vpi = io->node->vpi;
		io->iparam.fcp_tgt.rpi = io->node->rpi;
		io->iparam.fcp_tgt.s_id = io->node->port_fc_id;
		io->iparam.fcp_tgt.d_id = io->node->node_fc_id;
		io->iparam.fcp_tgt.xmit_len = io->wire_len;

		rc = efct_hw_io_send(&io->efct->hw, io->hio_type, io->hio,
				     &io->iparam, io->hw_cb, io);
		break;
	default:
		scsi_io_printf(io, "Unknown IO type=%d\n", io->io_type);
		rc = -EIO;
		break;
	}
	return rc;
}

static int
efct_scsi_io_dispatch_no_hw_io(struct efct_io *io)
{
	int rc;

	switch (io->io_type) {
	case EFCT_IO_TYPE_ABORT: {
		struct efct_hw_io *hio_to_abort = NULL;

		hio_to_abort = io->io_to_abort->hio;

		if (!hio_to_abort) {
			/*
			 * If "IO to abort" does not have an
			 * associated HW IO, immediately make callback with
			 * success. The command must have been sent to
			 * the backend, but the data phase has not yet
			 * started, so we don't have a HW IO.
			 *
			 * Note: since the backend shims should be
			 * taking a reference on io_to_abort, it should not
			 * be possible to have been completed and freed by
			 * the backend before the abort got here.
			 */
			scsi_io_printf(io, "IO: not active\n");
			((efct_hw_done_t)io->hw_cb)(io->hio, 0,
					SLI4_FC_WCQE_STATUS_SUCCESS, 0, io);
			rc = 0;
			break;
		}

		/* HW IO is valid, abort it */
		scsi_io_printf(io, "aborting\n");
		rc = efct_hw_io_abort(&io->efct->hw, hio_to_abort,
				      io->send_abts, io->hw_cb, io);
		if (rc) {
			int status = SLI4_FC_WCQE_STATUS_SUCCESS;
			efct_hw_done_t cb = io->hw_cb;

			if (rc != -ENOENT && rc != -EINPROGRESS) {
				status = -1;
				scsi_io_printf(io, "Failed to abort IO rc=%d\n",
					       rc);
			}
			cb(io->hio, 0, status, 0, io);
			rc = 0;
		}

		break;
	}
	default:
		scsi_io_printf(io, "Unknown IO type=%d\n", io->io_type);
		rc = -EIO;
		break;
	}
	return rc;
}

static struct efct_io *
efct_scsi_dispatch_pending(struct efct *efct)
{
	struct efct_xport *xport = efct->xport;
	struct efct_io *io = NULL;
	struct efct_hw_io *hio;
	unsigned long flags = 0;
	int status;

	spin_lock_irqsave(&xport->io_pending_lock, flags);

	if (!list_empty(&xport->io_pending_list)) {
		io = list_first_entry(&xport->io_pending_list, struct efct_io,
				      io_pending_link);
		list_del_init(&io->io_pending_link);
	}

	if (!io) {
		spin_unlock_irqrestore(&xport->io_pending_lock, flags);
		return NULL;
	}

	if (io->io_type == EFCT_IO_TYPE_ABORT) {
		hio = NULL;
	} else {
		hio = efct_hw_io_alloc(&efct->hw);
		if (!hio) {
			/*
			 * No HW IO available.Put IO back on
			 * the front of pending list
			 */
			list_add(&xport->io_pending_list, &io->io_pending_link);
			io = NULL;
		} else {
			hio->eq = io->hw_priv;
		}
	}

	/* Must drop the lock before dispatching the IO */
	spin_unlock_irqrestore(&xport->io_pending_lock, flags);

	if (!io)
		return NULL;

	/*
	 * We pulled an IO off the pending list,
	 * and either got an HW IO or don't need one
	 */
	atomic_sub_return(1, &xport->io_pending_count);
	if (!hio)
		status = efct_scsi_io_dispatch_no_hw_io(io);
	else
		status = efct_scsi_io_dispatch_hw_io(io, hio);
	if (status) {
		/*
		 * Invoke the HW callback, but do so in the
		 * separate execution context,provided by the
		 * NOP mailbox completion processing context
		 * by using efct_hw_async_call()
		 */
		if (efct_hw_async_call(&efct->hw,
				       efct_scsi_check_pending_async_cb, io)) {
			efc_log_debug(efct, "call hw async failed\n");
		}
	}

	return io;
}

void
efct_scsi_check_pending(struct efct *efct)
{
	struct efct_xport *xport = efct->xport;
	struct efct_io *io = NULL;
	int count = 0;
	unsigned long flags = 0;
	int dispatch = 0;

	/* Guard against recursion */
	if (atomic_add_return(1, &xport->io_pending_recursing)) {
		/* This function is already running.  Decrement and return. */
		atomic_sub_return(1, &xport->io_pending_recursing);
		return;
	}

	while (efct_scsi_dispatch_pending(efct))
		count++;

	if (count) {
		atomic_sub_return(1, &xport->io_pending_recursing);
		return;
	}

	/*
	 * If nothing was removed from the list,
	 * we might be in a case where we need to abort an
	 * active IO and the abort is on the pending list.
	 * Look for an abort we can dispatch.
	 */

	spin_lock_irqsave(&xport->io_pending_lock, flags);

	list_for_each_entry(io, &xport->io_pending_list, io_pending_link) {
		if (io->io_type == EFCT_IO_TYPE_ABORT && io->io_to_abort->hio) {
			/* This IO has a HW IO, so it is
			 * active.  Dispatch the abort.
			 */
			dispatch = 1;
			list_del_init(&io->io_pending_link);
			atomic_sub_return(1, &xport->io_pending_count);
			break;
		}
	}

	spin_unlock_irqrestore(&xport->io_pending_lock, flags);

	if (dispatch) {
		if (efct_scsi_io_dispatch_no_hw_io(io)) {
			if (efct_hw_async_call(&efct->hw,
				efct_scsi_check_pending_async_cb, io)) {
				efc_log_debug(efct, "hw async failed\n");
			}
		}
	}

	atomic_sub_return(1, &xport->io_pending_recursing);
}

int
efct_scsi_io_dispatch(struct efct_io *io, void *cb)
{
	struct efct_hw_io *hio;
	struct efct *efct = io->efct;
	struct efct_xport *xport = efct->xport;
	unsigned long flags = 0;

	io->hw_cb = cb;

	/*
	 * if this IO already has a HW IO, then this is either
	 * not the first phase of the IO. Send it to the HW.
	 */
	if (io->hio)
		return efct_scsi_io_dispatch_hw_io(io, io->hio);

	/*
	 * We don't already have a HW IO associated with the IO. First check
	 * the pending list. If not empty, add IO to the tail and process the
	 * pending list.
	 */
	spin_lock_irqsave(&xport->io_pending_lock, flags);
	if (!list_empty(&xport->io_pending_list)) {
		/*
		 * If this is a low latency request,
		 * the put at the front of the IO pending
		 * queue, otherwise put it at the end of the queue.
		 */
		if (io->low_latency) {
			INIT_LIST_HEAD(&io->io_pending_link);
			list_add(&xport->io_pending_list, &io->io_pending_link);
		} else {
			INIT_LIST_HEAD(&io->io_pending_link);
			list_add_tail(&io->io_pending_link,
				      &xport->io_pending_list);
		}
		spin_unlock_irqrestore(&xport->io_pending_lock, flags);
		atomic_add_return(1, &xport->io_pending_count);
		atomic_add_return(1, &xport->io_total_pending);

		/* process pending list */
		efct_scsi_check_pending(efct);
		return 0;
	}
	spin_unlock_irqrestore(&xport->io_pending_lock, flags);

	/*
	 * We don't have a HW IO associated with the IO and there's nothing
	 * on the pending list. Attempt to allocate a HW IO and dispatch it.
	 */
	hio = efct_hw_io_alloc(&io->efct->hw);
	if (!hio) {
		/* Couldn't get a HW IO. Save this IO on the pending list */
		spin_lock_irqsave(&xport->io_pending_lock, flags);
		INIT_LIST_HEAD(&io->io_pending_link);
		list_add_tail(&io->io_pending_link, &xport->io_pending_list);
		spin_unlock_irqrestore(&xport->io_pending_lock, flags);

		atomic_add_return(1, &xport->io_total_pending);
		atomic_add_return(1, &xport->io_pending_count);
		return 0;
	}

	/* We successfully allocated a HW IO; dispatch to HW */
	return efct_scsi_io_dispatch_hw_io(io, hio);
}

int
efct_scsi_io_dispatch_abort(struct efct_io *io, void *cb)
{
	struct efct *efct = io->efct;
	struct efct_xport *xport = efct->xport;
	unsigned long flags = 0;

	io->hw_cb = cb;

	/*
	 * For aborts, we don't need a HW IO, but we still want
	 * to pass through the pending list to preserve ordering.
	 * Thus, if the pending list is not empty, add this abort
	 * to the pending list and process the pending list.
	 */
	spin_lock_irqsave(&xport->io_pending_lock, flags);
	if (!list_empty(&xport->io_pending_list)) {
		INIT_LIST_HEAD(&io->io_pending_link);
		list_add_tail(&io->io_pending_link, &xport->io_pending_list);
		spin_unlock_irqrestore(&xport->io_pending_lock, flags);
		atomic_add_return(1, &xport->io_pending_count);
		atomic_add_return(1, &xport->io_total_pending);

		/* process pending list */
		efct_scsi_check_pending(efct);
		return 0;
	}
	spin_unlock_irqrestore(&xport->io_pending_lock, flags);

	/* nothing on pending list, dispatch abort */
	return efct_scsi_io_dispatch_no_hw_io(io);
}

static inline int
efct_scsi_xfer_data(struct efct_io *io, u32 flags,
		    struct efct_scsi_sgl *sgl, u32 sgl_count, u64 xwire_len,
		    enum efct_hw_io_type type, int enable_ar,
		    efct_scsi_io_cb_t cb, void *arg)
{
	struct efct *efct;
	size_t residual = 0;

	io->sgl_count = sgl_count;

	efct = io->efct;

	scsi_io_trace(io, "%s wire_len %llu\n",
		      (type == EFCT_HW_IO_TARGET_READ) ? "send" : "recv",
		      xwire_len);

	io->hio_type = type;

	io->scsi_tgt_cb = cb;
	io->scsi_tgt_cb_arg = arg;

	residual = io->exp_xfer_len - io->transferred;
	io->wire_len = (xwire_len < residual) ? xwire_len : residual;
	residual = (xwire_len - io->wire_len);

	memset(&io->iparam, 0, sizeof(io->iparam));
	io->iparam.fcp_tgt.ox_id = io->init_task_tag;
	io->iparam.fcp_tgt.offset = io->transferred;
	io->iparam.fcp_tgt.cs_ctl = io->cs_ctl;
	io->iparam.fcp_tgt.timeout = io->timeout;

	/* if this is the last data phase and there is no residual, enable
	 * auto-good-response
	 */
	if (enable_ar && (flags & EFCT_SCSI_LAST_DATAPHASE) && residual == 0 &&
	    ((io->transferred + io->wire_len) == io->exp_xfer_len) &&
	    (!(flags & EFCT_SCSI_NO_AUTO_RESPONSE))) {
		io->iparam.fcp_tgt.flags |= SLI4_IO_AUTO_GOOD_RESPONSE;
		io->auto_resp = true;
	} else {
		io->auto_resp = false;
	}

	/* save this transfer length */
	io->xfer_req = io->wire_len;

	/* Adjust the transferred count to account for overrun
	 * when the residual is calculated in efct_scsi_send_resp
	 */
	io->transferred += residual;

	/* Adjust the SGL size if there is overrun */

	if (residual) {
		struct efct_scsi_sgl  *sgl_ptr = &io->sgl[sgl_count - 1];

		while (residual) {
			size_t len = sgl_ptr->len;

			if (len > residual) {
				sgl_ptr->len = len - residual;
				residual = 0;
			} else {
				sgl_ptr->len = 0;
				residual -= len;
				io->sgl_count--;
			}
			sgl_ptr--;
		}
	}

	/* Set latency and WQ steering */
	io->low_latency = (flags & EFCT_SCSI_LOW_LATENCY) != 0;
	io->wq_steering = (flags & EFCT_SCSI_WQ_STEERING_MASK) >>
				EFCT_SCSI_WQ_STEERING_SHIFT;
	io->wq_class = (flags & EFCT_SCSI_WQ_CLASS_MASK) >>
				EFCT_SCSI_WQ_CLASS_SHIFT;

	if (efct->xport) {
		struct efct_xport *xport = efct->xport;

		if (type == EFCT_HW_IO_TARGET_READ) {
			xport->fcp_stats.input_requests++;
			xport->fcp_stats.input_bytes += xwire_len;
		} else if (type == EFCT_HW_IO_TARGET_WRITE) {
			xport->fcp_stats.output_requests++;
			xport->fcp_stats.output_bytes += xwire_len;
		}
	}
	return efct_scsi_io_dispatch(io, efct_target_io_cb);
}

int
efct_scsi_send_rd_data(struct efct_io *io, u32 flags,
		       struct efct_scsi_sgl *sgl, u32 sgl_count, u64 len,
		       efct_scsi_io_cb_t cb, void *arg)
{
	return efct_scsi_xfer_data(io, flags, sgl, sgl_count,
				   len, EFCT_HW_IO_TARGET_READ,
				   enable_tsend_auto_resp(io->efct), cb, arg);
}

int
efct_scsi_recv_wr_data(struct efct_io *io, u32 flags,
		       struct efct_scsi_sgl *sgl, u32 sgl_count, u64 len,
		       efct_scsi_io_cb_t cb, void *arg)
{
	return efct_scsi_xfer_data(io, flags, sgl, sgl_count, len,
				   EFCT_HW_IO_TARGET_WRITE,
				   enable_treceive_auto_resp(io->efct), cb, arg);
}

int
efct_scsi_send_resp(struct efct_io *io, u32 flags,
		    struct efct_scsi_cmd_resp *rsp,
		    efct_scsi_io_cb_t cb, void *arg)
{
	struct efct *efct;
	int residual;
	/* Always try auto resp */
	bool auto_resp = true;
	u8 scsi_status = 0;
	u16 scsi_status_qualifier = 0;
	u8 *sense_data = NULL;
	u32 sense_data_length = 0;

	efct = io->efct;

	if (rsp) {
		scsi_status = rsp->scsi_status;
		scsi_status_qualifier = rsp->scsi_status_qualifier;
		sense_data = rsp->sense_data;
		sense_data_length = rsp->sense_data_length;
		residual = rsp->residual;
	} else {
		residual = io->exp_xfer_len - io->transferred;
	}

	io->wire_len = 0;
	io->hio_type = EFCT_HW_IO_TARGET_RSP;

	io->scsi_tgt_cb = cb;
	io->scsi_tgt_cb_arg = arg;

	memset(&io->iparam, 0, sizeof(io->iparam));
	io->iparam.fcp_tgt.ox_id = io->init_task_tag;
	io->iparam.fcp_tgt.offset = 0;
	io->iparam.fcp_tgt.cs_ctl = io->cs_ctl;
	io->iparam.fcp_tgt.timeout = io->timeout;

	/* Set low latency queueing request */
	io->low_latency = (flags & EFCT_SCSI_LOW_LATENCY) != 0;
	io->wq_steering = (flags & EFCT_SCSI_WQ_STEERING_MASK) >>
				EFCT_SCSI_WQ_STEERING_SHIFT;
	io->wq_class = (flags & EFCT_SCSI_WQ_CLASS_MASK) >>
				EFCT_SCSI_WQ_CLASS_SHIFT;

	if (scsi_status != 0 || residual || sense_data_length) {
		struct fcp_resp_with_ext *fcprsp = io->rspbuf.virt;
		u8 *sns_data;

		if (!fcprsp) {
			efc_log_err(efct, "NULL response buffer\n");
			return -EIO;
		}

		sns_data = (u8 *)io->rspbuf.virt + sizeof(*fcprsp);

		auto_resp = false;

		memset(fcprsp, 0, sizeof(*fcprsp));

		io->wire_len += sizeof(*fcprsp);

		fcprsp->resp.fr_status = scsi_status;
		fcprsp->resp.fr_retry_delay =
			cpu_to_be16(scsi_status_qualifier);

		/* set residual status if necessary */
		if (residual != 0) {
			/* FCP: if data transferred is less than the
			 * amount expected, then this is an underflow.
			 * If data transferred would have been greater
			 * than the amount expected this is an overflow
			 */
			if (residual > 0) {
				fcprsp->resp.fr_flags |= FCP_RESID_UNDER;
				fcprsp->ext.fr_resid =	cpu_to_be32(residual);
			} else {
				fcprsp->resp.fr_flags |= FCP_RESID_OVER;
				fcprsp->ext.fr_resid = cpu_to_be32(-residual);
			}
		}

		if (EFCT_SCSI_SNS_BUF_VALID(sense_data) && sense_data_length) {
			if (sense_data_length > SCSI_SENSE_BUFFERSIZE) {
				efc_log_err(efct, "Sense exceeds max size.\n");
				return -EIO;
			}

			fcprsp->resp.fr_flags |= FCP_SNS_LEN_VAL;
			memcpy(sns_data, sense_data, sense_data_length);
			fcprsp->ext.fr_sns_len = cpu_to_be32(sense_data_length);
			io->wire_len += sense_data_length;
		}

		io->sgl[0].addr = io->rspbuf.phys;
		io->sgl[0].dif_addr = 0;
		io->sgl[0].len = io->wire_len;
		io->sgl_count = 1;
	}

	if (auto_resp)
		io->iparam.fcp_tgt.flags |= SLI4_IO_AUTO_GOOD_RESPONSE;

	return efct_scsi_io_dispatch(io, efct_target_io_cb);
}

static int
efct_target_bls_resp_cb(struct efct_hw_io *hio,	u32 length, int status,
			u32 ext_status, void *app)
{
	struct efct_io *io = app;
	struct efct *efct;
	enum efct_scsi_io_status bls_status;

	efct = io->efct;

	/* BLS isn't really a "SCSI" concept, but use SCSI status */
	if (status) {
		io_error_log(io, "s=%#x x=%#x\n", status, ext_status);
		bls_status = EFCT_SCSI_STATUS_ERROR;
	} else {
		bls_status = EFCT_SCSI_STATUS_GOOD;
	}

	if (io->bls_cb) {
		efct_scsi_io_cb_t bls_cb = io->bls_cb;
		void *bls_cb_arg = io->bls_cb_arg;

		io->bls_cb = NULL;
		io->bls_cb_arg = NULL;

		/* invoke callback */
		bls_cb(io, bls_status, 0, bls_cb_arg);
	}

	efct_scsi_check_pending(efct);
	return 0;
}

static int
efct_target_send_bls_resp(struct efct_io *io,
			  efct_scsi_io_cb_t cb, void *arg)
{
	struct efct_node *node = io->node;
	struct sli_bls_params *bls = &io->iparam.bls;
	struct efct *efct = node->efct;
	struct fc_ba_acc *acc;
	int rc;

	/* fill out IO structure with everything needed to send BA_ACC */
	memset(&io->iparam, 0, sizeof(io->iparam));
	bls->ox_id = io->init_task_tag;
	bls->rx_id = io->abort_rx_id;
	bls->vpi = io->node->vpi;
	bls->rpi = io->node->rpi;
	bls->s_id = U32_MAX;
	bls->d_id = io->node->node_fc_id;
	bls->rpi_registered = true;

	acc = (void *)bls->payload;
	acc->ba_ox_id = cpu_to_be16(bls->ox_id);
	acc->ba_rx_id = cpu_to_be16(bls->rx_id);
	acc->ba_high_seq_cnt = cpu_to_be16(U16_MAX);

	/* generic io fields have already been populated */

	/* set type and BLS-specific fields */
	io->io_type = EFCT_IO_TYPE_BLS_RESP;
	io->display_name = "bls_rsp";
	io->hio_type = EFCT_HW_BLS_ACC;
	io->bls_cb = cb;
	io->bls_cb_arg = arg;

	/* dispatch IO */
	rc = efct_hw_bls_send(efct, FC_RCTL_BA_ACC, bls,
			      efct_target_bls_resp_cb, io);
	return rc;
}

static int efct_bls_send_rjt_cb(struct efct_hw_io *hio, u32 length, int status,
				u32 ext_status, void *app)
{
	struct efct_io *io = app;

	efct_scsi_io_free(io);
	return 0;
}

struct efct_io *
efct_bls_send_rjt(struct efct_io *io, struct fc_frame_header *hdr)
{
	struct efct_node *node = io->node;
	struct sli_bls_params *bls = &io->iparam.bls;
	struct efct *efct = node->efct;
	struct fc_ba_rjt *acc;
	int rc;

	/* fill out BLS Response-specific fields */
	io->io_type = EFCT_IO_TYPE_BLS_RESP;
	io->display_name = "ba_rjt";
	io->hio_type = EFCT_HW_BLS_RJT;
	io->init_task_tag = be16_to_cpu(hdr->fh_ox_id);

	/* fill out iparam fields */
	memset(&io->iparam, 0, sizeof(io->iparam));
	bls->ox_id = be16_to_cpu(hdr->fh_ox_id);
	bls->rx_id = be16_to_cpu(hdr->fh_rx_id);
	bls->vpi = io->node->vpi;
	bls->rpi = io->node->rpi;
	bls->s_id = U32_MAX;
	bls->d_id = io->node->node_fc_id;
	bls->rpi_registered = true;

	acc = (void *)bls->payload;
	acc->br_reason = ELS_RJT_UNAB;
	acc->br_explan = ELS_EXPL_NONE;

	rc = efct_hw_bls_send(efct, FC_RCTL_BA_RJT, bls, efct_bls_send_rjt_cb,
			      io);
	if (rc) {
		efc_log_err(efct, "efct_scsi_io_dispatch() failed: %d\n", rc);
		efct_scsi_io_free(io);
		io = NULL;
	}
	return io;
}

int
efct_scsi_send_tmf_resp(struct efct_io *io,
			enum efct_scsi_tmf_resp rspcode,
			u8 addl_rsp_info[3],
			efct_scsi_io_cb_t cb, void *arg)
{
	int rc;
	struct {
		struct fcp_resp_with_ext rsp_ext;
		struct fcp_resp_rsp_info info;
	} *fcprsp;
	u8 fcp_rspcode;

	io->wire_len = 0;

	switch (rspcode) {
	case EFCT_SCSI_TMF_FUNCTION_COMPLETE:
		fcp_rspcode = FCP_TMF_CMPL;
		break;
	case EFCT_SCSI_TMF_FUNCTION_SUCCEEDED:
	case EFCT_SCSI_TMF_FUNCTION_IO_NOT_FOUND:
		fcp_rspcode = FCP_TMF_CMPL;
		break;
	case EFCT_SCSI_TMF_FUNCTION_REJECTED:
		fcp_rspcode = FCP_TMF_REJECTED;
		break;
	case EFCT_SCSI_TMF_INCORRECT_LOGICAL_UNIT_NUMBER:
		fcp_rspcode = FCP_TMF_INVALID_LUN;
		break;
	case EFCT_SCSI_TMF_SERVICE_DELIVERY:
		fcp_rspcode = FCP_TMF_FAILED;
		break;
	default:
		fcp_rspcode = FCP_TMF_REJECTED;
		break;
	}

	io->hio_type = EFCT_HW_IO_TARGET_RSP;

	io->scsi_tgt_cb = cb;
	io->scsi_tgt_cb_arg = arg;

	if (io->tmf_cmd == EFCT_SCSI_TMF_ABORT_TASK) {
		rc = efct_target_send_bls_resp(io, cb, arg);
		return rc;
	}

	/* populate the FCP TMF response */
	fcprsp = io->rspbuf.virt;
	memset(fcprsp, 0, sizeof(*fcprsp));

	fcprsp->rsp_ext.resp.fr_flags |= FCP_SNS_LEN_VAL;

	if (addl_rsp_info) {
		memcpy(fcprsp->info._fr_resvd, addl_rsp_info,
		       sizeof(fcprsp->info._fr_resvd));
	}
	fcprsp->info.rsp_code = fcp_rspcode;

	io->wire_len = sizeof(*fcprsp);

	fcprsp->rsp_ext.ext.fr_rsp_len =
			cpu_to_be32(sizeof(struct fcp_resp_rsp_info));

	io->sgl[0].addr = io->rspbuf.phys;
	io->sgl[0].dif_addr = 0;
	io->sgl[0].len = io->wire_len;
	io->sgl_count = 1;

	memset(&io->iparam, 0, sizeof(io->iparam));
	io->iparam.fcp_tgt.ox_id = io->init_task_tag;
	io->iparam.fcp_tgt.offset = 0;
	io->iparam.fcp_tgt.cs_ctl = io->cs_ctl;
	io->iparam.fcp_tgt.timeout = io->timeout;

	rc = efct_scsi_io_dispatch(io, efct_target_io_cb);

	return rc;
}

static int
efct_target_abort_cb(struct efct_hw_io *hio, u32 length, int status,
		     u32 ext_status, void *app)
{
	struct efct_io *io = app;
	struct efct *efct;
	enum efct_scsi_io_status scsi_status;
	efct_scsi_io_cb_t abort_cb;
	void *abort_cb_arg;

	efct = io->efct;

	if (!io->abort_cb)
		goto done;

	abort_cb = io->abort_cb;
	abort_cb_arg = io->abort_cb_arg;

	io->abort_cb = NULL;
	io->abort_cb_arg = NULL;

	switch (status) {
	case SLI4_FC_WCQE_STATUS_SUCCESS:
		scsi_status = EFCT_SCSI_STATUS_GOOD;
		break;
	case SLI4_FC_WCQE_STATUS_LOCAL_REJECT:
		switch (ext_status) {
		case SLI4_FC_LOCAL_REJECT_NO_XRI:
			scsi_status = EFCT_SCSI_STATUS_NO_IO;
			break;
		case SLI4_FC_LOCAL_REJECT_ABORT_IN_PROGRESS:
			scsi_status = EFCT_SCSI_STATUS_ABORT_IN_PROGRESS;
			break;
		default:
			/*we have seen 0x15 (abort in progress)*/
			scsi_status = EFCT_SCSI_STATUS_ERROR;
			break;
		}
		break;
	case SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE:
		scsi_status = EFCT_SCSI_STATUS_CHECK_RESPONSE;
		break;
	default:
		scsi_status = EFCT_SCSI_STATUS_ERROR;
		break;
	}
	/* invoke callback */
	abort_cb(io->io_to_abort, scsi_status, 0, abort_cb_arg);

done:
	/* done with IO to abort,efct_ref_get(): efct_scsi_tgt_abort_io() */
	kref_put(&io->io_to_abort->ref, io->io_to_abort->release);

	efct_io_pool_io_free(efct->xport->io_pool, io);

	efct_scsi_check_pending(efct);
	return 0;
}

int
efct_scsi_tgt_abort_io(struct efct_io *io, efct_scsi_io_cb_t cb, void *arg)
{
	struct efct *efct;
	struct efct_xport *xport;
	int rc;
	struct efct_io *abort_io = NULL;

	efct = io->efct;
	xport = efct->xport;

	/* take a reference on IO being aborted */
	if (kref_get_unless_zero(&io->ref) == 0) {
		/* command no longer active */
		scsi_io_printf(io, "command no longer active\n");
		return -EIO;
	}

	/*
	 * allocate a new IO to send the abort request. Use efct_io_alloc()
	 * directly, as we need an IO object that will not fail allocation
	 * due to allocations being disabled (in efct_scsi_io_alloc())
	 */
	abort_io = efct_io_pool_io_alloc(efct->xport->io_pool);
	if (!abort_io) {
		atomic_add_return(1, &xport->io_alloc_failed_count);
		kref_put(&io->ref, io->release);
		return -EIO;
	}

	/* Save the target server callback and argument */
	/* set generic fields */
	abort_io->cmd_tgt = true;
	abort_io->node = io->node;

	/* set type and abort-specific fields */
	abort_io->io_type = EFCT_IO_TYPE_ABORT;
	abort_io->display_name = "tgt_abort";
	abort_io->io_to_abort = io;
	abort_io->send_abts = false;
	abort_io->abort_cb = cb;
	abort_io->abort_cb_arg = arg;

	/* now dispatch IO */
	rc = efct_scsi_io_dispatch_abort(abort_io, efct_target_abort_cb);
	if (rc)
		kref_put(&io->ref, io->release);
	return rc;
}

void
efct_scsi_io_complete(struct efct_io *io)
{
	if (io->io_free) {
		efc_log_debug(io->efct, "completion for non-busy io tag 0x%x\n",
			      io->tag);
		return;
	}

	scsi_io_trace(io, "freeing io 0x%p %s\n", io, io->display_name);
	kref_put(&io->ref, io->release);
}
