// 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 = 0;

	efct = node->efct;

	xport = efct->xport;

	spin_lock_irqsave(&node->active_ios_lock, flags);

	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);
		spin_unlock_irqrestore(&node->active_ios_lock, flags);
		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);
	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);
}
