// SPDX-License-Identifier: GPL-2.0-only
/*
 * QLogic Fibre Channel HBA Driver
 * Copyright (c)  2003-2017 QLogic Corporation
 */
#include "qla_nvme.h"
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/nvme.h>
#include <linux/nvme-fc.h>
#include <linux/blk-mq-pci.h>
#include <linux/blk-mq.h>

static struct nvme_fc_port_template qla_nvme_fc_transport;
static int qla_nvme_ls_reject_iocb(struct scsi_qla_host *vha,
				   struct qla_qpair *qp,
				   struct qla_nvme_lsrjt_pt_arg *a,
				   bool is_xchg_terminate);

struct qla_nvme_unsol_ctx {
	struct list_head elem;
	struct scsi_qla_host *vha;
	struct fc_port *fcport;
	struct srb *sp;
	struct nvmefc_ls_rsp lsrsp;
	struct nvmefc_ls_rsp *fd_rsp;
	struct work_struct lsrsp_work;
	struct work_struct abort_work;
	__le32 exchange_address;
	__le16 nport_handle;
	__le16 ox_id;
	int comp_status;
	spinlock_t cmd_lock;
};

int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
{
	struct qla_nvme_rport *rport;
	struct nvme_fc_port_info req;
	int ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return 0;

	if (!vha->flags.nvme_enabled) {
		ql_log(ql_log_info, vha, 0x2100,
		    "%s: Not registering target since Host NVME is not enabled\n",
		    __func__);
		return 0;
	}

	if (qla_nvme_register_hba(vha))
		return 0;

	if (!vha->nvme_local_port)
		return 0;

	if (!(fcport->nvme_prli_service_param &
	    (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
		(fcport->nvme_flag & NVME_FLAG_REGISTERED))
		return 0;

	fcport->nvme_flag &= ~NVME_FLAG_RESETTING;

	memset(&req, 0, sizeof(struct nvme_fc_port_info));
	req.port_name = wwn_to_u64(fcport->port_name);
	req.node_name = wwn_to_u64(fcport->node_name);
	req.port_role = 0;
	req.dev_loss_tmo = fcport->dev_loss_tmo;

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR)
		req.port_role = FC_PORT_ROLE_NVME_INITIATOR;

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET)
		req.port_role |= FC_PORT_ROLE_NVME_TARGET;

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY)
		req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY;

	req.port_id = fcport->d_id.b24;

	ql_log(ql_log_info, vha, 0x2102,
	    "%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n",
	    __func__, req.node_name, req.port_name,
	    req.port_id);

	ret = nvme_fc_register_remoteport(vha->nvme_local_port, &req,
	    &fcport->nvme_remote_port);
	if (ret) {
		ql_log(ql_log_warn, vha, 0x212e,
		    "Failed to register remote port. Transport returned %d\n",
		    ret);
		return ret;
	}

	nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port,
				       fcport->dev_loss_tmo);

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_SLER)
		ql_log(ql_log_info, vha, 0x212a,
		       "PortID:%06x Supports SLER\n", req.port_id);

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_PI_CTRL)
		ql_log(ql_log_info, vha, 0x212b,
		       "PortID:%06x Supports PI control\n", req.port_id);

	rport = fcport->nvme_remote_port->private;
	rport->fcport = fcport;

	fcport->nvme_flag |= NVME_FLAG_REGISTERED;
	return 0;
}

/* Allocate a queue for NVMe traffic */
static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport,
    unsigned int qidx, u16 qsize, void **handle)
{
	struct scsi_qla_host *vha;
	struct qla_hw_data *ha;
	struct qla_qpair *qpair;

	/* Map admin queue and 1st IO queue to index 0 */
	if (qidx)
		qidx--;

	vha = (struct scsi_qla_host *)lport->private;
	ha = vha->hw;

	ql_log(ql_log_info, vha, 0x2104,
	    "%s: handle %p, idx =%d, qsize %d\n",
	    __func__, handle, qidx, qsize);

	if (qidx > qla_nvme_fc_transport.max_hw_queues) {
		ql_log(ql_log_warn, vha, 0x212f,
		    "%s: Illegal qidx=%d. Max=%d\n",
		    __func__, qidx, qla_nvme_fc_transport.max_hw_queues);
		return -EINVAL;
	}

	/* Use base qpair if max_qpairs is 0 */
	if (!ha->max_qpairs) {
		qpair = ha->base_qpair;
	} else {
		if (ha->queue_pair_map[qidx]) {
			*handle = ha->queue_pair_map[qidx];
			ql_log(ql_log_info, vha, 0x2121,
			       "Returning existing qpair of %p for idx=%x\n",
			       *handle, qidx);
			return 0;
		}

		qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true);
		if (!qpair) {
			ql_log(ql_log_warn, vha, 0x2122,
			       "Failed to allocate qpair\n");
			return -EINVAL;
		}
		qla_adjust_iocb_limit(vha);
	}
	*handle = qpair;

	return 0;
}

static void qla_nvme_release_fcp_cmd_kref(struct kref *kref)
{
	struct srb *sp = container_of(kref, struct srb, cmd_kref);
	struct nvme_private *priv = (struct nvme_private *)sp->priv;
	struct nvmefc_fcp_req *fd;
	struct srb_iocb *nvme;
	unsigned long flags;

	if (!priv)
		goto out;

	nvme = &sp->u.iocb_cmd;
	fd = nvme->u.nvme.desc;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	priv->sp = NULL;
	sp->priv = NULL;
	if (priv->comp_status == QLA_SUCCESS) {
		fd->rcv_rsplen = le16_to_cpu(nvme->u.nvme.rsp_pyld_len);
		fd->status = NVME_SC_SUCCESS;
	} else {
		fd->rcv_rsplen = 0;
		fd->transferred_length = 0;
		fd->status = NVME_SC_INTERNAL;
	}
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	fd->done(fd);
out:
	qla2xxx_rel_qpair_sp(sp->qpair, sp);
}

static void qla_nvme_release_ls_cmd_kref(struct kref *kref)
{
	struct srb *sp = container_of(kref, struct srb, cmd_kref);
	struct nvme_private *priv = (struct nvme_private *)sp->priv;
	struct nvmefc_ls_req *fd;
	unsigned long flags;

	if (!priv)
		goto out;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	priv->sp = NULL;
	sp->priv = NULL;
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	fd = priv->fd;

	fd->done(fd, priv->comp_status);
out:
	qla2x00_rel_sp(sp);
}

static void qla_nvme_ls_complete(struct work_struct *work)
{
	struct nvme_private *priv =
		container_of(work, struct nvme_private, ls_work);

	kref_put(&priv->sp->cmd_kref, qla_nvme_release_ls_cmd_kref);
}

static void qla_nvme_sp_ls_done(srb_t *sp, int res)
{
	struct nvme_private *priv = sp->priv;

	if (WARN_ON_ONCE(kref_read(&sp->cmd_kref) == 0))
		return;

	if (res)
		res = -EINVAL;

	priv->comp_status = res;
	INIT_WORK(&priv->ls_work, qla_nvme_ls_complete);
	schedule_work(&priv->ls_work);
}

static void qla_nvme_release_lsrsp_cmd_kref(struct kref *kref)
{
	struct srb *sp = container_of(kref, struct srb, cmd_kref);
	struct qla_nvme_unsol_ctx *uctx = sp->priv;
	struct nvmefc_ls_rsp *fd_rsp;
	unsigned long flags;

	if (!uctx) {
		qla2x00_rel_sp(sp);
		return;
	}

	spin_lock_irqsave(&uctx->cmd_lock, flags);
	uctx->sp = NULL;
	sp->priv = NULL;
	spin_unlock_irqrestore(&uctx->cmd_lock, flags);

	fd_rsp = uctx->fd_rsp;

	list_del(&uctx->elem);

	fd_rsp->done(fd_rsp);
	kfree(uctx);
	qla2x00_rel_sp(sp);
}

static void qla_nvme_lsrsp_complete(struct work_struct *work)
{
	struct qla_nvme_unsol_ctx *uctx =
		container_of(work, struct qla_nvme_unsol_ctx, lsrsp_work);

	kref_put(&uctx->sp->cmd_kref, qla_nvme_release_lsrsp_cmd_kref);
}

static void qla_nvme_sp_lsrsp_done(srb_t *sp, int res)
{
	struct qla_nvme_unsol_ctx *uctx = sp->priv;

	if (WARN_ON_ONCE(kref_read(&sp->cmd_kref) == 0))
		return;

	if (res)
		res = -EINVAL;

	uctx->comp_status = res;
	INIT_WORK(&uctx->lsrsp_work, qla_nvme_lsrsp_complete);
	schedule_work(&uctx->lsrsp_work);
}

/* it assumed that QPair lock is held. */
static void qla_nvme_sp_done(srb_t *sp, int res)
{
	struct nvme_private *priv = sp->priv;

	priv->comp_status = res;
	kref_put(&sp->cmd_kref, qla_nvme_release_fcp_cmd_kref);

	return;
}

static void qla_nvme_abort_work(struct work_struct *work)
{
	struct nvme_private *priv =
		container_of(work, struct nvme_private, abort_work);
	srb_t *sp = priv->sp;
	fc_port_t *fcport = sp->fcport;
	struct qla_hw_data *ha = fcport->vha->hw;
	int rval, abts_done_called = 1;
	bool io_wait_for_abort_done;
	uint32_t handle;

	ql_dbg(ql_dbg_io, fcport->vha, 0xffff,
	       "%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n",
	       __func__, sp, sp->handle, fcport, sp->u.iocb_cmd.u.nvme.desc, fcport->deleted);

	if (!ha->flags.fw_started || fcport->deleted == QLA_SESS_DELETED)
		goto out;

	if (ha->flags.host_shutting_down) {
		ql_log(ql_log_info, sp->fcport->vha, 0xffff,
		    "%s Calling done on sp: %p, type: 0x%x\n",
		    __func__, sp, sp->type);
		sp->done(sp, 0);
		goto out;
	}

	/*
	 * sp may not be valid after abort_command if return code is either
	 * SUCCESS or ERR_FROM_FW codes, so cache the value here.
	 */
	io_wait_for_abort_done = ql2xabts_wait_nvme &&
					QLA_ABTS_WAIT_ENABLED(sp);
	handle = sp->handle;

	rval = ha->isp_ops->abort_command(sp);

	ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
	    "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n",
	    __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
	    sp, handle, fcport, rval);

	/*
	 * If async tmf is enabled, the abort callback is called only on
	 * return codes QLA_SUCCESS and QLA_ERR_FROM_FW.
	 */
	if (ql2xasynctmfenable &&
	    rval != QLA_SUCCESS && rval != QLA_ERR_FROM_FW)
		abts_done_called = 0;

	/*
	 * Returned before decreasing kref so that I/O requests
	 * are waited until ABTS complete. This kref is decreased
	 * at qla24xx_abort_sp_done function.
	 */
	if (abts_done_called && io_wait_for_abort_done)
		return;
out:
	/* kref_get was done before work was schedule. */
	kref_put(&sp->cmd_kref, sp->put_fn);
}

static int qla_nvme_xmt_ls_rsp(struct nvme_fc_local_port *lport,
			       struct nvme_fc_remote_port *rport,
			       struct nvmefc_ls_rsp *fd_resp)
{
	struct qla_nvme_unsol_ctx *uctx = container_of(fd_resp,
				struct qla_nvme_unsol_ctx, lsrsp);
	struct qla_nvme_rport *qla_rport = rport->private;
	fc_port_t *fcport = qla_rport->fcport;
	struct scsi_qla_host *vha = uctx->vha;
	struct qla_hw_data *ha = vha->hw;
	struct qla_nvme_lsrjt_pt_arg a;
	struct srb_iocb *nvme;
	srb_t *sp;
	int rval = QLA_FUNCTION_FAILED;
	uint8_t cnt = 0;

	if (!fcport || fcport->deleted)
		goto out;

	if (!ha->flags.fw_started)
		goto out;

	/* Alloc SRB structure */
	sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
	if (!sp)
		goto out;

	sp->type = SRB_NVME_LS;
	sp->name = "nvme_ls";
	sp->done = qla_nvme_sp_lsrsp_done;
	sp->put_fn = qla_nvme_release_lsrsp_cmd_kref;
	sp->priv = (void *)uctx;
	sp->unsol_rsp = 1;
	uctx->sp = sp;
	spin_lock_init(&uctx->cmd_lock);
	nvme = &sp->u.iocb_cmd;
	uctx->fd_rsp = fd_resp;
	nvme->u.nvme.desc = fd_resp;
	nvme->u.nvme.dir = 0;
	nvme->u.nvme.dl = 0;
	nvme->u.nvme.timeout_sec = 0;
	nvme->u.nvme.cmd_dma = fd_resp->rspdma;
	nvme->u.nvme.cmd_len = cpu_to_le32(fd_resp->rsplen);
	nvme->u.nvme.rsp_len = 0;
	nvme->u.nvme.rsp_dma = 0;
	nvme->u.nvme.exchange_address = uctx->exchange_address;
	nvme->u.nvme.nport_handle = uctx->nport_handle;
	nvme->u.nvme.ox_id = uctx->ox_id;
	dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
				   fd_resp->rsplen, DMA_TO_DEVICE);

	ql_dbg(ql_dbg_unsol, vha, 0x2122,
	       "Unsol lsreq portid=%06x %8phC exchange_address 0x%x ox_id 0x%x hdl 0x%x\n",
	       fcport->d_id.b24, fcport->port_name, uctx->exchange_address,
	       uctx->ox_id, uctx->nport_handle);
retry:
	rval = qla2x00_start_sp(sp);
	switch (rval) {
	case QLA_SUCCESS:
		break;
	case EAGAIN:
		msleep(PURLS_MSLEEP_INTERVAL);
		cnt++;
		if (cnt < PURLS_RETRY_COUNT)
			goto retry;

		fallthrough;
	default:
		ql_dbg(ql_log_warn, vha, 0x2123,
		       "Failed to xmit Unsol ls response = %d\n", rval);
		rval = -EIO;
		qla2x00_rel_sp(sp);
		goto out;
	}

	return 0;
out:
	memset((void *)&a, 0, sizeof(a));
	a.vp_idx = vha->vp_idx;
	a.nport_handle = uctx->nport_handle;
	a.xchg_address = uctx->exchange_address;
	qla_nvme_ls_reject_iocb(vha, ha->base_qpair, &a, true);
	kfree(uctx);
	return rval;
}

static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
{
	struct nvme_private *priv = fd->private;
	unsigned long flags;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	if (!priv->sp) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}

	if (!kref_get_unless_zero(&priv->sp->cmd_kref)) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
	schedule_work(&priv->abort_work);
}

static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
{
	struct qla_nvme_rport *qla_rport = rport->private;
	fc_port_t *fcport = qla_rport->fcport;
	struct srb_iocb   *nvme;
	struct nvme_private *priv = fd->private;
	struct scsi_qla_host *vha;
	int     rval = QLA_FUNCTION_FAILED;
	struct qla_hw_data *ha;
	srb_t           *sp;

	if (!fcport || fcport->deleted)
		return rval;

	vha = fcport->vha;
	ha = vha->hw;

	if (!ha->flags.fw_started)
		return rval;

	/* Alloc SRB structure */
	sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
	if (!sp)
		return rval;

	sp->type = SRB_NVME_LS;
	sp->name = "nvme_ls";
	sp->done = qla_nvme_sp_ls_done;
	sp->put_fn = qla_nvme_release_ls_cmd_kref;
	sp->priv = priv;
	priv->sp = sp;
	kref_init(&sp->cmd_kref);
	spin_lock_init(&priv->cmd_lock);
	nvme = &sp->u.iocb_cmd;
	priv->fd = fd;
	nvme->u.nvme.desc = fd;
	nvme->u.nvme.dir = 0;
	nvme->u.nvme.dl = 0;
	nvme->u.nvme.cmd_len = cpu_to_le32(fd->rqstlen);
	nvme->u.nvme.rsp_len = cpu_to_le32(fd->rsplen);
	nvme->u.nvme.rsp_dma = fd->rspdma;
	nvme->u.nvme.timeout_sec = fd->timeout;
	nvme->u.nvme.cmd_dma = fd->rqstdma;
	dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
	    fd->rqstlen, DMA_TO_DEVICE);

	rval = qla2x00_start_sp(sp);
	if (rval != QLA_SUCCESS) {
		ql_log(ql_log_warn, vha, 0x700e,
		    "qla2x00_start_sp failed = %d\n", rval);
		sp->priv = NULL;
		priv->sp = NULL;
		qla2x00_rel_sp(sp);
		return rval;
	}

	return rval;
}

static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, void *hw_queue_handle,
    struct nvmefc_fcp_req *fd)
{
	struct nvme_private *priv = fd->private;
	unsigned long flags;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	if (!priv->sp) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}
	if (!kref_get_unless_zero(&priv->sp->cmd_kref)) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
	schedule_work(&priv->abort_work);
}

static inline int qla2x00_start_nvme_mq(srb_t *sp)
{
	unsigned long   flags;
	uint32_t        *clr_ptr;
	uint32_t        handle;
	struct cmd_nvme *cmd_pkt;
	uint16_t        cnt, i;
	uint16_t        req_cnt;
	uint16_t        tot_dsds;
	uint16_t	avail_dsds;
	struct dsd64	*cur_dsd;
	struct req_que *req = NULL;
	struct rsp_que *rsp = NULL;
	struct scsi_qla_host *vha = sp->fcport->vha;
	struct qla_hw_data *ha = vha->hw;
	struct qla_qpair *qpair = sp->qpair;
	struct srb_iocb *nvme = &sp->u.iocb_cmd;
	struct scatterlist *sgl, *sg;
	struct nvmefc_fcp_req *fd = nvme->u.nvme.desc;
	struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
	uint32_t        rval = QLA_SUCCESS;

	/* Setup qpair pointers */
	req = qpair->req;
	rsp = qpair->rsp;
	tot_dsds = fd->sg_cnt;

	/* Acquire qpair specific lock */
	spin_lock_irqsave(&qpair->qp_lock, flags);

	handle = qla2xxx_get_next_handle(req);
	if (handle == 0) {
		rval = -EBUSY;
		goto queuing_error;
	}
	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);

	sp->iores.res_type = RESOURCE_IOCB | RESOURCE_EXCH;
	sp->iores.exch_cnt = 1;
	sp->iores.iocb_cnt = req_cnt;
	if (qla_get_fw_resources(sp->qpair, &sp->iores)) {
		rval = -EBUSY;
		goto queuing_error;
	}

	if (req->cnt < (req_cnt + 2)) {
		if (IS_SHADOW_REG_CAPABLE(ha)) {
			cnt = *req->out_ptr;
		} else {
			cnt = rd_reg_dword_relaxed(req->req_q_out);
			if (qla2x00_check_reg16_for_disconnect(vha, cnt)) {
				rval = -EBUSY;
				goto queuing_error;
			}
		}

		if (req->ring_index < cnt)
			req->cnt = cnt - req->ring_index;
		else
			req->cnt = req->length - (req->ring_index - cnt);

		if (req->cnt < (req_cnt + 2)){
			rval = -EBUSY;
			goto queuing_error;
		}
	}

	if (unlikely(!fd->sqid)) {
		if (cmd->sqe.common.opcode == nvme_admin_async_event) {
			nvme->u.nvme.aen_op = 1;
			atomic_inc(&ha->nvme_active_aen_cnt);
		}
	}

	/* Build command packet. */
	req->current_outstanding_cmd = handle;
	req->outstanding_cmds[handle] = sp;
	sp->handle = handle;
	req->cnt -= req_cnt;

	cmd_pkt = (struct cmd_nvme *)req->ring_ptr;
	cmd_pkt->handle = make_handle(req->id, handle);

	/* Zero out remaining portion of packet. */
	clr_ptr = (uint32_t *)cmd_pkt + 2;
	memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);

	cmd_pkt->entry_status = 0;

	/* Update entry type to indicate Command NVME IOCB */
	cmd_pkt->entry_type = COMMAND_NVME;

	/* No data transfer how do we check buffer len == 0?? */
	if (fd->io_dir == NVMEFC_FCP_READ) {
		cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
		qpair->counters.input_bytes += fd->payload_length;
		qpair->counters.input_requests++;
	} else if (fd->io_dir == NVMEFC_FCP_WRITE) {
		cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
		if ((vha->flags.nvme_first_burst) &&
		    (sp->fcport->nvme_prli_service_param &
			NVME_PRLI_SP_FIRST_BURST)) {
			if ((fd->payload_length <=
			    sp->fcport->nvme_first_burst_size) ||
				(sp->fcport->nvme_first_burst_size == 0))
				cmd_pkt->control_flags |=
					cpu_to_le16(CF_NVME_FIRST_BURST_ENABLE);
		}
		qpair->counters.output_bytes += fd->payload_length;
		qpair->counters.output_requests++;
	} else if (fd->io_dir == 0) {
		cmd_pkt->control_flags = 0;
	}

	if (sp->fcport->edif.enable && fd->io_dir != 0)
		cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF);

	/* Set BIT_13 of control flags for Async event */
	if (vha->flags.nvme2_enabled &&
	    cmd->sqe.common.opcode == nvme_admin_async_event) {
		cmd_pkt->control_flags |= cpu_to_le16(CF_ADMIN_ASYNC_EVENT);
	}

	/* Set NPORT-ID */
	cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
	cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
	cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
	cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
	cmd_pkt->vp_index = sp->fcport->vha->vp_idx;

	/* NVME RSP IU */
	cmd_pkt->nvme_rsp_dsd_len = cpu_to_le16(fd->rsplen);
	put_unaligned_le64(fd->rspdma, &cmd_pkt->nvme_rsp_dseg_address);

	/* NVME CNMD IU */
	cmd_pkt->nvme_cmnd_dseg_len = cpu_to_le16(fd->cmdlen);
	cmd_pkt->nvme_cmnd_dseg_address = cpu_to_le64(fd->cmddma);

	cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
	cmd_pkt->byte_count = cpu_to_le32(fd->payload_length);

	/* One DSD is available in the Command Type NVME IOCB */
	avail_dsds = 1;
	cur_dsd = &cmd_pkt->nvme_dsd;
	sgl = fd->first_sgl;

	/* Load data segments */
	for_each_sg(sgl, sg, tot_dsds, i) {
		cont_a64_entry_t *cont_pkt;

		/* Allocate additional continuation packets? */
		if (avail_dsds == 0) {
			/*
			 * Five DSDs are available in the Continuation
			 * Type 1 IOCB.
			 */

			/* Adjust ring index */
			req->ring_index++;
			if (req->ring_index == req->length) {
				req->ring_index = 0;
				req->ring_ptr = req->ring;
			} else {
				req->ring_ptr++;
			}
			cont_pkt = (cont_a64_entry_t *)req->ring_ptr;
			put_unaligned_le32(CONTINUE_A64_TYPE,
					   &cont_pkt->entry_type);

			cur_dsd = cont_pkt->dsd;
			avail_dsds = ARRAY_SIZE(cont_pkt->dsd);
		}

		append_dsd64(&cur_dsd, sg);
		avail_dsds--;
	}

	/* Set total entry count. */
	cmd_pkt->entry_count = (uint8_t)req_cnt;
	wmb();

	/* Adjust ring index. */
	req->ring_index++;
	if (req->ring_index == req->length) {
		req->ring_index = 0;
		req->ring_ptr = req->ring;
	} else {
		req->ring_ptr++;
	}

	/* ignore nvme async cmd due to long timeout */
	if (!nvme->u.nvme.aen_op)
		sp->qpair->cmd_cnt++;

	/* Set chip new ring index. */
	wrt_reg_dword(req->req_q_in, req->ring_index);

	if (vha->flags.process_response_queue &&
	    rsp->ring_ptr->signature != RESPONSE_PROCESSED)
		qla24xx_process_response_queue(vha, rsp);

queuing_error:
	if (rval)
		qla_put_fw_resources(sp->qpair, &sp->iores);
	spin_unlock_irqrestore(&qpair->qp_lock, flags);

	return rval;
}

/* Post a command */
static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, void *hw_queue_handle,
    struct nvmefc_fcp_req *fd)
{
	fc_port_t *fcport;
	struct srb_iocb *nvme;
	struct scsi_qla_host *vha;
	struct qla_hw_data *ha;
	int rval;
	srb_t *sp;
	struct qla_qpair *qpair = hw_queue_handle;
	struct nvme_private *priv = fd->private;
	struct qla_nvme_rport *qla_rport = rport->private;

	if (!priv) {
		/* nvme association has been torn down */
		return -ENODEV;
	}

	fcport = qla_rport->fcport;

	if (unlikely(!qpair || !fcport || fcport->deleted))
		return -EBUSY;

	if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))
		return -ENODEV;

	vha = fcport->vha;
	ha = vha->hw;

	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
		return -EBUSY;

	/*
	 * If we know the dev is going away while the transport is still sending
	 * IO's return busy back to stall the IO Q.  This happens when the
	 * link goes away and fw hasn't notified us yet, but IO's are being
	 * returned. If the dev comes back quickly we won't exhaust the IO
	 * retry count at the core.
	 */
	if (fcport->nvme_flag & NVME_FLAG_RESETTING)
		return -EBUSY;

	qpair = qla_mapq_nvme_select_qpair(ha, qpair);

	/* Alloc SRB structure */
	sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
	if (!sp)
		return -EBUSY;

	kref_init(&sp->cmd_kref);
	spin_lock_init(&priv->cmd_lock);
	sp->priv = priv;
	priv->sp = sp;
	sp->type = SRB_NVME_CMD;
	sp->name = "nvme_cmd";
	sp->done = qla_nvme_sp_done;
	sp->put_fn = qla_nvme_release_fcp_cmd_kref;
	sp->qpair = qpair;
	sp->vha = vha;
	sp->cmd_sp = sp;
	nvme = &sp->u.iocb_cmd;
	nvme->u.nvme.desc = fd;

	rval = qla2x00_start_nvme_mq(sp);
	if (rval != QLA_SUCCESS) {
		ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x212d,
		    "qla2x00_start_nvme_mq failed = %d\n", rval);
		sp->priv = NULL;
		priv->sp = NULL;
		qla2xxx_rel_qpair_sp(sp->qpair, sp);
	}

	return rval;
}

static void qla_nvme_map_queues(struct nvme_fc_local_port *lport,
		struct blk_mq_queue_map *map)
{
	struct scsi_qla_host *vha = lport->private;

	blk_mq_pci_map_queues(map, vha->hw->pdev, vha->irq_offset);
}

static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport)
{
	struct scsi_qla_host *vha = lport->private;

	ql_log(ql_log_info, vha, 0x210f,
	    "localport delete of %p completed.\n", vha->nvme_local_port);
	vha->nvme_local_port = NULL;
	complete(&vha->nvme_del_done);
}

static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
{
	fc_port_t *fcport;
	struct qla_nvme_rport *qla_rport = rport->private;

	fcport = qla_rport->fcport;
	fcport->nvme_remote_port = NULL;
	fcport->nvme_flag &= ~NVME_FLAG_REGISTERED;
	fcport->nvme_flag &= ~NVME_FLAG_DELETING;
	ql_log(ql_log_info, fcport->vha, 0x2110,
	    "remoteport_delete of %p %8phN completed.\n",
	    fcport, fcport->port_name);
	complete(&fcport->nvme_del_done);
}

static struct nvme_fc_port_template qla_nvme_fc_transport = {
	.localport_delete = qla_nvme_localport_delete,
	.remoteport_delete = qla_nvme_remoteport_delete,
	.create_queue   = qla_nvme_alloc_queue,
	.delete_queue 	= NULL,
	.ls_req		= qla_nvme_ls_req,
	.ls_abort	= qla_nvme_ls_abort,
	.fcp_io		= qla_nvme_post_cmd,
	.fcp_abort	= qla_nvme_fcp_abort,
	.xmt_ls_rsp	= qla_nvme_xmt_ls_rsp,
	.map_queues	= qla_nvme_map_queues,
	.max_hw_queues  = DEF_NVME_HW_QUEUES,
	.max_sgl_segments = 1024,
	.max_dif_sgl_segments = 64,
	.dma_boundary = 0xFFFFFFFF,
	.local_priv_sz  = 8,
	.remote_priv_sz = sizeof(struct qla_nvme_rport),
	.lsrqst_priv_sz = sizeof(struct nvme_private),
	.fcprqst_priv_sz = sizeof(struct nvme_private),
};

void qla_nvme_unregister_remote_port(struct fc_port *fcport)
{
	int ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return;

	ql_log(ql_log_warn, fcport->vha, 0x2112,
	    "%s: unregister remoteport on %p %8phN\n",
	    __func__, fcport, fcport->port_name);

	if (test_bit(PFLG_DRIVER_REMOVING, &fcport->vha->pci_flags))
		nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0);

	init_completion(&fcport->nvme_del_done);
	ret = nvme_fc_unregister_remoteport(fcport->nvme_remote_port);
	if (ret)
		ql_log(ql_log_info, fcport->vha, 0x2114,
			"%s: Failed to unregister nvme_remote_port (%d)\n",
			    __func__, ret);
	wait_for_completion(&fcport->nvme_del_done);
}

void qla_nvme_delete(struct scsi_qla_host *vha)
{
	int nv_ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return;

	if (vha->nvme_local_port) {
		init_completion(&vha->nvme_del_done);
		ql_log(ql_log_info, vha, 0x2116,
			"unregister localport=%p\n",
			vha->nvme_local_port);
		nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port);
		if (nv_ret)
			ql_log(ql_log_info, vha, 0x2115,
			    "Unregister of localport failed\n");
		else
			wait_for_completion(&vha->nvme_del_done);
	}
}

int qla_nvme_register_hba(struct scsi_qla_host *vha)
{
	struct nvme_fc_port_template *tmpl;
	struct qla_hw_data *ha;
	struct nvme_fc_port_info pinfo;
	int ret = -EINVAL;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return ret;

	ha = vha->hw;
	tmpl = &qla_nvme_fc_transport;

	if (ql2xnvme_queues < MIN_NVME_HW_QUEUES) {
		ql_log(ql_log_warn, vha, 0xfffd,
		    "ql2xnvme_queues=%d is lower than minimum queues: %d. Resetting ql2xnvme_queues to:%d\n",
		    ql2xnvme_queues, MIN_NVME_HW_QUEUES, DEF_NVME_HW_QUEUES);
		ql2xnvme_queues = DEF_NVME_HW_QUEUES;
	} else if (ql2xnvme_queues > (ha->max_qpairs - 1)) {
		ql_log(ql_log_warn, vha, 0xfffd,
		       "ql2xnvme_queues=%d is greater than available IRQs: %d. Resetting ql2xnvme_queues to: %d\n",
		       ql2xnvme_queues, (ha->max_qpairs - 1),
		       (ha->max_qpairs - 1));
		ql2xnvme_queues = ((ha->max_qpairs - 1));
	}

	qla_nvme_fc_transport.max_hw_queues =
	    min((uint8_t)(ql2xnvme_queues),
		(uint8_t)((ha->max_qpairs - 1) ? (ha->max_qpairs - 1) : 1));

	ql_log(ql_log_info, vha, 0xfffb,
	       "Number of NVME queues used for this port: %d\n",
	    qla_nvme_fc_transport.max_hw_queues);

	pinfo.node_name = wwn_to_u64(vha->node_name);
	pinfo.port_name = wwn_to_u64(vha->port_name);
	pinfo.port_role = FC_PORT_ROLE_NVME_INITIATOR;
	pinfo.port_id = vha->d_id.b24;

	mutex_lock(&ha->vport_lock);
	/*
	 * Check again for nvme_local_port to see if any other thread raced
	 * with this one and finished registration.
	 */
	if (!vha->nvme_local_port) {
		ql_log(ql_log_info, vha, 0xffff,
		    "register_localport: host-traddr=nn-0x%llx:pn-0x%llx on portID:%x\n",
		    pinfo.node_name, pinfo.port_name, pinfo.port_id);
		qla_nvme_fc_transport.dma_boundary = vha->host->dma_boundary;

		ret = nvme_fc_register_localport(&pinfo, tmpl,
						 get_device(&ha->pdev->dev),
						 &vha->nvme_local_port);
		mutex_unlock(&ha->vport_lock);
	} else {
		mutex_unlock(&ha->vport_lock);
		return 0;
	}
	if (ret) {
		ql_log(ql_log_warn, vha, 0xffff,
		    "register_localport failed: ret=%x\n", ret);
	} else {
		vha->nvme_local_port->private = vha;
	}

	return ret;
}

void qla_nvme_abort_set_option(struct abort_entry_24xx *abt, srb_t *orig_sp)
{
	struct qla_hw_data *ha;

	if (!(ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(orig_sp)))
		return;

	ha = orig_sp->fcport->vha->hw;

	WARN_ON_ONCE(abt->options & cpu_to_le16(BIT_0));
	/* Use Driver Specified Retry Count */
	abt->options |= cpu_to_le16(AOF_ABTS_RTY_CNT);
	abt->drv.abts_rty_cnt = cpu_to_le16(2);
	/* Use specified response timeout */
	abt->options |= cpu_to_le16(AOF_RSP_TIMEOUT);
	/* set it to 2 * r_a_tov in secs */
	abt->drv.rsp_timeout = cpu_to_le16(2 * (ha->r_a_tov / 10));
}

void qla_nvme_abort_process_comp_status(struct abort_entry_24xx *abt, srb_t *orig_sp)
{
	u16	comp_status;
	struct scsi_qla_host *vha;

	if (!(ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(orig_sp)))
		return;

	vha = orig_sp->fcport->vha;

	comp_status = le16_to_cpu(abt->comp_status);
	switch (comp_status) {
	case CS_RESET:		/* reset event aborted */
	case CS_ABORTED:	/* IOCB was cleaned */
	/* N_Port handle is not currently logged in */
	case CS_TIMEOUT:
	/* N_Port handle was logged out while waiting for ABTS to complete */
	case CS_PORT_UNAVAILABLE:
	/* Firmware found that the port name changed */
	case CS_PORT_LOGGED_OUT:
	/* BA_RJT was received for the ABTS */
	case CS_PORT_CONFIG_CHG:
		ql_dbg(ql_dbg_async, vha, 0xf09d,
		       "Abort I/O IOCB completed with error, comp_status=%x\n",
		comp_status);
		break;

	/* BA_RJT was received for the ABTS */
	case CS_REJECT_RECEIVED:
		ql_dbg(ql_dbg_async, vha, 0xf09e,
		       "BA_RJT was received for the ABTS rjt_vendorUnique = %u",
			abt->fw.ba_rjt_vendorUnique);
		ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09e,
		       "ba_rjt_reasonCodeExpl = %u, ba_rjt_reasonCode = %u\n",
		       abt->fw.ba_rjt_reasonCodeExpl, abt->fw.ba_rjt_reasonCode);
		break;

	case CS_COMPLETE:
		ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0xf09f,
		       "IOCB request is completed successfully comp_status=%x\n",
		comp_status);
		break;

	case CS_IOCB_ERROR:
		ql_dbg(ql_dbg_async, vha, 0xf0a0,
		       "IOCB request is failed, comp_status=%x\n", comp_status);
		break;

	default:
		ql_dbg(ql_dbg_async, vha, 0xf0a1,
		       "Invalid Abort IO IOCB Completion Status %x\n",
		comp_status);
		break;
	}
}

inline void qla_wait_nvme_release_cmd_kref(srb_t *orig_sp)
{
	if (!(ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(orig_sp)))
		return;
	kref_put(&orig_sp->cmd_kref, orig_sp->put_fn);
}

static void qla_nvme_fc_format_rjt(void *buf, u8 ls_cmd, u8 reason,
				   u8 explanation, u8 vendor)
{
	struct fcnvme_ls_rjt *rjt = buf;

	rjt->w0.ls_cmd = FCNVME_LSDESC_RQST;
	rjt->desc_list_len = fcnvme_lsdesc_len(sizeof(struct fcnvme_ls_rjt));
	rjt->rqst.desc_tag = cpu_to_be32(FCNVME_LSDESC_RQST);
	rjt->rqst.desc_len =
		fcnvme_lsdesc_len(sizeof(struct fcnvme_lsdesc_rqst));
	rjt->rqst.w0.ls_cmd = ls_cmd;
	rjt->rjt.desc_tag = cpu_to_be32(FCNVME_LSDESC_RJT);
	rjt->rjt.desc_len = fcnvme_lsdesc_len(sizeof(struct fcnvme_lsdesc_rjt));
	rjt->rjt.reason_code = reason;
	rjt->rjt.reason_explanation = explanation;
	rjt->rjt.vendor = vendor;
}

static void qla_nvme_lsrjt_pt_iocb(struct scsi_qla_host *vha,
				   struct pt_ls4_request *lsrjt_iocb,
				   struct qla_nvme_lsrjt_pt_arg *a)
{
	lsrjt_iocb->entry_type = PT_LS4_REQUEST;
	lsrjt_iocb->entry_count = 1;
	lsrjt_iocb->sys_define = 0;
	lsrjt_iocb->entry_status = 0;
	lsrjt_iocb->handle = QLA_SKIP_HANDLE;
	lsrjt_iocb->nport_handle = a->nport_handle;
	lsrjt_iocb->exchange_address = a->xchg_address;
	lsrjt_iocb->vp_index = a->vp_idx;

	lsrjt_iocb->control_flags = cpu_to_le16(a->control_flags);

	put_unaligned_le64(a->tx_addr, &lsrjt_iocb->dsd[0].address);
	lsrjt_iocb->dsd[0].length = cpu_to_le32(a->tx_byte_count);
	lsrjt_iocb->tx_dseg_count = cpu_to_le16(1);
	lsrjt_iocb->tx_byte_count = cpu_to_le32(a->tx_byte_count);

	put_unaligned_le64(a->rx_addr, &lsrjt_iocb->dsd[1].address);
	lsrjt_iocb->dsd[1].length = 0;
	lsrjt_iocb->rx_dseg_count = 0;
	lsrjt_iocb->rx_byte_count = 0;
}

static int
qla_nvme_ls_reject_iocb(struct scsi_qla_host *vha, struct qla_qpair *qp,
			struct qla_nvme_lsrjt_pt_arg *a, bool is_xchg_terminate)
{
	struct pt_ls4_request *lsrjt_iocb;

	lsrjt_iocb = __qla2x00_alloc_iocbs(qp, NULL);
	if (!lsrjt_iocb) {
		ql_log(ql_log_warn, vha, 0x210e,
		       "qla2x00_alloc_iocbs failed.\n");
		return QLA_FUNCTION_FAILED;
	}

	if (!is_xchg_terminate) {
		qla_nvme_fc_format_rjt((void *)vha->hw->lsrjt.c, a->opcode,
				       a->reason, a->explanation, 0);

		a->tx_byte_count = sizeof(struct fcnvme_ls_rjt);
		a->tx_addr = vha->hw->lsrjt.cdma;
		a->control_flags = CF_LS4_RESPONDER << CF_LS4_SHIFT;

		ql_dbg(ql_dbg_unsol, vha, 0x211f,
		       "Sending nvme fc ls reject ox_id %04x op %04x\n",
		       a->ox_id, a->opcode);
		ql_dump_buffer(ql_dbg_unsol + ql_dbg_verbose, vha, 0x210f,
			       vha->hw->lsrjt.c, sizeof(*vha->hw->lsrjt.c));
	} else {
		a->tx_byte_count = 0;
		a->control_flags = CF_LS4_RESPONDER_TERM << CF_LS4_SHIFT;
		ql_dbg(ql_dbg_unsol, vha, 0x2110,
		       "Terminate nvme ls xchg 0x%x\n", a->xchg_address);
	}

	qla_nvme_lsrjt_pt_iocb(vha, lsrjt_iocb, a);
	/* flush iocb to mem before notifying hw doorbell */
	wmb();
	qla2x00_start_iocbs(vha, qp->req);
	return 0;
}

/*
 * qla2xxx_process_purls_pkt() - Pass-up Unsolicited
 * Received FC-NVMe Link Service pkt to nvme_fc_rcv_ls_req().
 * LLDD need to provide memory for response buffer, which
 * will be used to reference the exchange corresponding
 * to the LS when issuing an ls response. LLDD will have to free
 * response buffer in lport->ops->xmt_ls_rsp().
 *
 * @vha: SCSI qla host
 * @item: ptr to purex_item
 */
static void
qla2xxx_process_purls_pkt(struct scsi_qla_host *vha, struct purex_item *item)
{
	struct qla_nvme_unsol_ctx *uctx = item->purls_context;
	struct qla_nvme_lsrjt_pt_arg a;
	int ret = 1;

#if (IS_ENABLED(CONFIG_NVME_FC))
	ret = nvme_fc_rcv_ls_req(uctx->fcport->nvme_remote_port, &uctx->lsrsp,
				 &item->iocb, item->size);
#endif
	if (ret) {
		ql_dbg(ql_dbg_unsol, vha, 0x2125, "NVMe transport ls_req failed\n");
		memset((void *)&a, 0, sizeof(a));
		a.vp_idx = vha->vp_idx;
		a.nport_handle = uctx->nport_handle;
		a.xchg_address = uctx->exchange_address;
		qla_nvme_ls_reject_iocb(vha, vha->hw->base_qpair, &a, true);
		list_del(&uctx->elem);
		kfree(uctx);
	}
}

static scsi_qla_host_t *
qla2xxx_get_vha_from_vp_idx(struct qla_hw_data *ha, uint16_t vp_index)
{
	scsi_qla_host_t *base_vha, *vha, *tvp;
	unsigned long flags;

	base_vha = pci_get_drvdata(ha->pdev);

	if (!vp_index && !ha->num_vhosts)
		return base_vha;

	spin_lock_irqsave(&ha->vport_slock, flags);
	list_for_each_entry_safe(vha, tvp, &ha->vp_list, list) {
		if (vha->vp_idx == vp_index) {
			spin_unlock_irqrestore(&ha->vport_slock, flags);
			return vha;
		}
	}
	spin_unlock_irqrestore(&ha->vport_slock, flags);

	return NULL;
}

void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp)
{
	struct nvme_fc_remote_port *rport;
	struct qla_nvme_rport *qla_rport;
	struct qla_nvme_lsrjt_pt_arg a;
	struct pt_ls4_rx_unsol *p = *pkt;
	struct qla_nvme_unsol_ctx *uctx;
	struct rsp_que *rsp_q = *rsp;
	struct qla_hw_data *ha;
	scsi_qla_host_t	*vha;
	fc_port_t *fcport = NULL;
	struct purex_item *item;
	port_id_t d_id = {0};
	port_id_t id = {0};
	u8 *opcode;
	bool xmt_reject = false;

	ha = rsp_q->hw;

	vha = qla2xxx_get_vha_from_vp_idx(ha, p->vp_index);
	if (!vha) {
		ql_log(ql_log_warn, NULL, 0x2110, "Invalid vp index %d\n", p->vp_index);
		WARN_ON_ONCE(1);
		return;
	}

	memset((void *)&a, 0, sizeof(a));
	opcode = (u8 *)&p->payload[0];
	a.opcode = opcode[3];
	a.vp_idx = p->vp_index;
	a.nport_handle = p->nport_handle;
	a.ox_id = p->ox_id;
	a.xchg_address = p->exchange_address;

	id.b.domain = p->s_id.domain;
	id.b.area   = p->s_id.area;
	id.b.al_pa  = p->s_id.al_pa;
	d_id.b.domain = p->d_id[2];
	d_id.b.area   = p->d_id[1];
	d_id.b.al_pa  = p->d_id[0];

	fcport = qla2x00_find_fcport_by_nportid(vha, &id, 0);
	if (!fcport) {
		ql_dbg(ql_dbg_unsol, vha, 0x211e,
		       "Failed to find sid=%06x did=%06x\n",
		       id.b24, d_id.b24);
		a.reason = FCNVME_RJT_RC_INV_ASSOC;
		a.explanation = FCNVME_RJT_EXP_NONE;
		xmt_reject = true;
		goto out;
	}
	rport = fcport->nvme_remote_port;
	qla_rport = rport->private;

	item = qla27xx_copy_multiple_pkt(vha, pkt, rsp, true, false);
	if (!item) {
		a.reason = FCNVME_RJT_RC_LOGIC;
		a.explanation = FCNVME_RJT_EXP_NONE;
		xmt_reject = true;
		goto out;
	}

	uctx = kzalloc(sizeof(*uctx), GFP_ATOMIC);
	if (!uctx) {
		ql_log(ql_log_info, vha, 0x2126, "Failed allocate memory\n");
		a.reason = FCNVME_RJT_RC_LOGIC;
		a.explanation = FCNVME_RJT_EXP_NONE;
		xmt_reject = true;
		kfree(item);
		goto out;
	}

	uctx->vha = vha;
	uctx->fcport = fcport;
	uctx->exchange_address = p->exchange_address;
	uctx->nport_handle = p->nport_handle;
	uctx->ox_id = p->ox_id;
	qla_rport->uctx = uctx;
	INIT_LIST_HEAD(&uctx->elem);
	list_add_tail(&uctx->elem, &fcport->unsol_ctx_head);
	item->purls_context = (void *)uctx;

	ql_dbg(ql_dbg_unsol, vha, 0x2121,
	       "PURLS OP[%01x] size %d xchg addr 0x%x portid %06x\n",
	       item->iocb.iocb[3], item->size, uctx->exchange_address,
	       fcport->d_id.b24);
	/* +48    0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
	 * ----- -----------------------------------------------
	 * 0000: 00 00 00 05 28 00 00 00 07 00 00 00 08 00 00 00
	 * 0010: ab ec 0f cc 00 00 8d 7d 05 00 00 00 10 00 00 00
	 * 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
	 */
	ql_dump_buffer(ql_dbg_unsol + ql_dbg_verbose, vha, 0x2120,
		       &item->iocb, item->size);

	qla24xx_queue_purex_item(vha, item, qla2xxx_process_purls_pkt);
out:
	if (xmt_reject) {
		qla_nvme_ls_reject_iocb(vha, (*rsp)->qpair, &a, false);
		__qla_consume_iocb(vha, pkt, rsp);
	}
}
