|
Hannes Reinecke |
cc93a0 |
From: James Smart <jsmart2021@gmail.com>
|
|
Hannes Reinecke |
cc93a0 |
Date: Tue, 31 Mar 2020 09:50:08 -0700
|
|
Hannes Reinecke |
cc93a0 |
Subject: [PATCH] lpfc: Refactor Send LS Response support
|
|
Hannes Reinecke |
cc93a0 |
Git-commit: d17bb8a5d9b171706fb145039ea38fccc2d47728
|
|
Hannes Reinecke |
cc93a0 |
Git-repo: git://git.infradead.org/nvme.git
|
|
Hannes Reinecke |
cc93a0 |
Patch-mainline: Queued in subsystem maintainer repository
|
|
Hannes Reinecke |
cc93a0 |
References: bsc#1169045
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
Currently, the ability to send an NVME LS response is limited to the nvmet
|
|
Hannes Reinecke |
cc93a0 |
(controller/target) side of the driver. In preparation of both the nvme
|
|
Hannes Reinecke |
cc93a0 |
and nvmet sides supporting Send LS Response, rework the existing send
|
|
Hannes Reinecke |
cc93a0 |
ls_rsp and ls_rsp completion routines such that there is common code that
|
|
Hannes Reinecke |
cc93a0 |
can be used by both sides.
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
Signed-off-by: Paul Ely <paul.ely@broadcom.com>
|
|
Hannes Reinecke |
cc93a0 |
Signed-off-by: James Smart <jsmart2021@gmail.com>
|
|
Hannes Reinecke |
cc93a0 |
Reviewed-by: Hannes Reinecke <hare@suse.de>
|
|
Hannes Reinecke |
cc93a0 |
Signed-off-by: Christoph Hellwig <hch@lst.de>
|
|
Hannes Reinecke |
cc93a0 |
Acked-by: Hannes Reinecke <hare@suse.com>
|
|
Hannes Reinecke |
cc93a0 |
---
|
|
Hannes Reinecke |
cc93a0 |
drivers/scsi/lpfc/lpfc_nvme.h | 7 ++
|
|
Hannes Reinecke |
cc93a0 |
drivers/scsi/lpfc/lpfc_nvmet.c | 255 ++++++++++++++++++++++++++++-------------
|
|
Hannes Reinecke |
cc93a0 |
2 files changed, 184 insertions(+), 78 deletions(-)
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h
|
|
Hannes Reinecke |
cc93a0 |
index a9ad81d0c182..f28a6789e252 100644
|
|
Hannes Reinecke |
cc93a0 |
--- a/drivers/scsi/lpfc/lpfc_nvme.h
|
|
Hannes Reinecke |
cc93a0 |
+++ b/drivers/scsi/lpfc/lpfc_nvme.h
|
|
Hannes Reinecke |
cc93a0 |
@@ -244,3 +244,10 @@ int __lpfc_nvme_ls_abort(struct lpfc_vport *vport,
|
|
Hannes Reinecke |
cc93a0 |
int lpfc_nvme_unsol_ls_issue_abort(struct lpfc_hba *phba,
|
|
Hannes Reinecke |
cc93a0 |
struct lpfc_async_xchg_ctx *ctxp, uint32_t sid,
|
|
Hannes Reinecke |
cc93a0 |
uint16_t xri);
|
|
Hannes Reinecke |
cc93a0 |
+int __lpfc_nvme_xmt_ls_rsp(struct lpfc_async_xchg_ctx *axchg,
|
|
Hannes Reinecke |
cc93a0 |
+ struct nvmefc_ls_rsp *ls_rsp,
|
|
Hannes Reinecke |
cc93a0 |
+ void (*xmt_ls_rsp_cmp)(struct lpfc_hba *phba,
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_iocbq *cmdwqe,
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_wcqe_complete *wcqe));
|
|
Hannes Reinecke |
cc93a0 |
+void __lpfc_nvme_xmt_ls_rsp_cmp(struct lpfc_hba *phba,
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_iocbq *cmdwqe, struct lpfc_wcqe_complete *wcqe);
|
|
Hannes Reinecke |
cc93a0 |
diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c
|
|
Hannes Reinecke |
cc93a0 |
index e6895c719683..edec7c3ffab1 100644
|
|
Hannes Reinecke |
cc93a0 |
--- a/drivers/scsi/lpfc/lpfc_nvmet.c
|
|
Hannes Reinecke |
cc93a0 |
+++ b/drivers/scsi/lpfc/lpfc_nvmet.c
|
|
Hannes Reinecke |
cc93a0 |
@@ -280,6 +280,53 @@ lpfc_nvmet_defer_release(struct lpfc_hba *phba,
|
|
Hannes Reinecke |
cc93a0 |
spin_unlock(&phba->sli4_hba.abts_nvmet_buf_list_lock);
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
+/**
|
|
Hannes Reinecke |
cc93a0 |
+ * __lpfc_nvme_xmt_ls_rsp_cmp - Generic completion handler for the
|
|
Hannes Reinecke |
cc93a0 |
+ * transmission of an NVME LS response.
|
|
Hannes Reinecke |
cc93a0 |
+ * @phba: Pointer to HBA context object.
|
|
Hannes Reinecke |
cc93a0 |
+ * @cmdwqe: Pointer to driver command WQE object.
|
|
Hannes Reinecke |
cc93a0 |
+ * @wcqe: Pointer to driver response CQE object.
|
|
Hannes Reinecke |
cc93a0 |
+ *
|
|
Hannes Reinecke |
cc93a0 |
+ * The function is called from SLI ring event handler with no
|
|
Hannes Reinecke |
cc93a0 |
+ * lock held. The function frees memory resources used for the command
|
|
Hannes Reinecke |
cc93a0 |
+ * used to send the NVME LS RSP.
|
|
Hannes Reinecke |
cc93a0 |
+ **/
|
|
Hannes Reinecke |
cc93a0 |
+void
|
|
Hannes Reinecke |
cc93a0 |
+__lpfc_nvme_xmt_ls_rsp_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_wcqe_complete *wcqe)
|
|
Hannes Reinecke |
cc93a0 |
+{
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_async_xchg_ctx *axchg = cmdwqe->context2;
|
|
Hannes Reinecke |
cc93a0 |
+ struct nvmefc_ls_rsp *ls_rsp = &axchg->ls_rsp;
|
|
Hannes Reinecke |
cc93a0 |
+ uint32_t status, result;
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ status = bf_get(lpfc_wcqe_c_status, wcqe) & LPFC_IOCB_STATUS_MASK;
|
|
Hannes Reinecke |
cc93a0 |
+ result = wcqe->parameter;
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ if (axchg->state != LPFC_NVME_STE_LS_RSP || axchg->entry_cnt != 2) {
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC | LOG_NVME_IOERR,
|
|
Hannes Reinecke |
cc93a0 |
+ "6410 NVMEx LS cmpl state mismatch IO x%x: "
|
|
Hannes Reinecke |
cc93a0 |
+ "%d %d\n",
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->oxid, axchg->state, axchg->entry_cnt);
|
|
Hannes Reinecke |
cc93a0 |
+ }
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_nvmeio_data(phba, "NVMEx LS CMPL: xri x%x stat x%x result x%x\n",
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->oxid, status, result);
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
|
|
Hannes Reinecke |
cc93a0 |
+ "6038 NVMEx LS rsp cmpl: %d %d oxid x%x\n",
|
|
Hannes Reinecke |
cc93a0 |
+ status, result, axchg->oxid);
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_nlp_put(cmdwqe->context1);
|
|
Hannes Reinecke |
cc93a0 |
+ cmdwqe->context2 = NULL;
|
|
Hannes Reinecke |
cc93a0 |
+ cmdwqe->context3 = NULL;
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_sli_release_iocbq(phba, cmdwqe);
|
|
Hannes Reinecke |
cc93a0 |
+ ls_rsp->done(ls_rsp);
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
|
|
Hannes Reinecke |
cc93a0 |
+ "6200 NVMEx LS rsp cmpl done status %d oxid x%x\n",
|
|
Hannes Reinecke |
cc93a0 |
+ status, axchg->oxid);
|
|
Hannes Reinecke |
cc93a0 |
+ kfree(axchg);
|
|
Hannes Reinecke |
cc93a0 |
+}
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
/**
|
|
Hannes Reinecke |
cc93a0 |
* lpfc_nvmet_xmt_ls_rsp_cmp - Completion handler for LS Response
|
|
Hannes Reinecke |
cc93a0 |
* @phba: Pointer to HBA context object.
|
|
Hannes Reinecke |
cc93a0 |
@@ -288,33 +335,23 @@ lpfc_nvmet_defer_release(struct lpfc_hba *phba,
|
|
Hannes Reinecke |
cc93a0 |
*
|
|
Hannes Reinecke |
cc93a0 |
* The function is called from SLI ring event handler with no
|
|
Hannes Reinecke |
cc93a0 |
* lock held. This function is the completion handler for NVME LS commands
|
|
Hannes Reinecke |
cc93a0 |
- * The function frees memory resources used for the NVME commands.
|
|
Hannes Reinecke |
cc93a0 |
+ * The function updates any states and statistics, then calls the
|
|
Hannes Reinecke |
cc93a0 |
+ * generic completion handler to free resources.
|
|
Hannes Reinecke |
cc93a0 |
**/
|
|
Hannes Reinecke |
cc93a0 |
static void
|
|
Hannes Reinecke |
cc93a0 |
lpfc_nvmet_xmt_ls_rsp_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
|
|
Hannes Reinecke |
cc93a0 |
struct lpfc_wcqe_complete *wcqe)
|
|
Hannes Reinecke |
cc93a0 |
{
|
|
Hannes Reinecke |
cc93a0 |
struct lpfc_nvmet_tgtport *tgtp;
|
|
Hannes Reinecke |
cc93a0 |
- struct nvmefc_ls_rsp *rsp;
|
|
Hannes Reinecke |
cc93a0 |
- struct lpfc_async_xchg_ctx *ctxp;
|
|
Hannes Reinecke |
cc93a0 |
uint32_t status, result;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- status = bf_get(lpfc_wcqe_c_status, wcqe);
|
|
Hannes Reinecke |
cc93a0 |
- result = wcqe->parameter;
|
|
Hannes Reinecke |
cc93a0 |
- ctxp = cmdwqe->context2;
|
|
Hannes Reinecke |
cc93a0 |
-
|
|
Hannes Reinecke |
cc93a0 |
- if (ctxp->state != LPFC_NVME_STE_LS_RSP || ctxp->entry_cnt != 2) {
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
|
|
Hannes Reinecke |
cc93a0 |
- "6410 NVMET LS cmpl state mismatch IO x%x: "
|
|
Hannes Reinecke |
cc93a0 |
- "%d %d\n",
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->oxid, ctxp->state, ctxp->entry_cnt);
|
|
Hannes Reinecke |
cc93a0 |
- }
|
|
Hannes Reinecke |
cc93a0 |
-
|
|
Hannes Reinecke |
cc93a0 |
if (!phba->targetport)
|
|
Hannes Reinecke |
cc93a0 |
- goto out;
|
|
Hannes Reinecke |
cc93a0 |
+ goto finish;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
|
Hannes Reinecke |
cc93a0 |
+ status = bf_get(lpfc_wcqe_c_status, wcqe) & LPFC_IOCB_STATUS_MASK;
|
|
Hannes Reinecke |
cc93a0 |
+ result = wcqe->parameter;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
+ tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private;
|
|
Hannes Reinecke |
cc93a0 |
if (tgtp) {
|
|
Hannes Reinecke |
cc93a0 |
if (status) {
|
|
Hannes Reinecke |
cc93a0 |
atomic_inc(&tgtp->xmt_ls_rsp_error);
|
|
Hannes Reinecke |
cc93a0 |
@@ -327,22 +364,8 @@ lpfc_nvmet_xmt_ls_rsp_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
-out:
|
|
Hannes Reinecke |
cc93a0 |
- rsp = &ctxp->ls_rsp;
|
|
Hannes Reinecke |
cc93a0 |
-
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_nvmeio_data(phba, "NVMET LS CMPL: xri x%x stat x%x result x%x\n",
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->oxid, status, result);
|
|
Hannes Reinecke |
cc93a0 |
-
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
|
|
Hannes Reinecke |
cc93a0 |
- "6038 NVMET LS rsp cmpl: %d %d oxid x%x\n",
|
|
Hannes Reinecke |
cc93a0 |
- status, result, ctxp->oxid);
|
|
Hannes Reinecke |
cc93a0 |
-
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_nlp_put(cmdwqe->context1);
|
|
Hannes Reinecke |
cc93a0 |
- cmdwqe->context2 = NULL;
|
|
Hannes Reinecke |
cc93a0 |
- cmdwqe->context3 = NULL;
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_sli_release_iocbq(phba, cmdwqe);
|
|
Hannes Reinecke |
cc93a0 |
- rsp->done(rsp);
|
|
Hannes Reinecke |
cc93a0 |
- kfree(ctxp);
|
|
Hannes Reinecke |
cc93a0 |
+finish:
|
|
Hannes Reinecke |
cc93a0 |
+ __lpfc_nvme_xmt_ls_rsp_cmp(phba, cmdwqe, wcqe);
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
/**
|
|
Hannes Reinecke |
cc93a0 |
@@ -821,52 +844,61 @@ lpfc_nvmet_xmt_fcp_op_cmp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdwqe,
|
|
Hannes Reinecke |
cc93a0 |
#endif
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
-static int
|
|
Hannes Reinecke |
cc93a0 |
-lpfc_nvmet_xmt_ls_rsp(struct nvmet_fc_target_port *tgtport,
|
|
Hannes Reinecke |
cc93a0 |
- struct nvmefc_ls_rsp *rsp)
|
|
Hannes Reinecke |
cc93a0 |
+/**
|
|
Hannes Reinecke |
cc93a0 |
+ * __lpfc_nvme_xmt_ls_rsp - Generic service routine to issue transmit
|
|
Hannes Reinecke |
cc93a0 |
+ * an NVME LS rsp for a prior NVME LS request that was received.
|
|
Hannes Reinecke |
cc93a0 |
+ * @axchg: pointer to exchange context for the NVME LS request the response
|
|
Hannes Reinecke |
cc93a0 |
+ * is for.
|
|
Hannes Reinecke |
cc93a0 |
+ * @ls_rsp: pointer to the transport LS RSP that is to be sent
|
|
Hannes Reinecke |
cc93a0 |
+ * @xmt_ls_rsp_cmp: completion routine to call upon RSP transmit done
|
|
Hannes Reinecke |
cc93a0 |
+ *
|
|
Hannes Reinecke |
cc93a0 |
+ * This routine is used to format and send a WQE to transmit a NVME LS
|
|
Hannes Reinecke |
cc93a0 |
+ * Response. The response is for a prior NVME LS request that was
|
|
Hannes Reinecke |
cc93a0 |
+ * received and posted to the transport.
|
|
Hannes Reinecke |
cc93a0 |
+ *
|
|
Hannes Reinecke |
cc93a0 |
+ * Returns:
|
|
Hannes Reinecke |
cc93a0 |
+ * 0 : if response successfully transmit
|
|
Hannes Reinecke |
cc93a0 |
+ * non-zero : if response failed to transmit, of the form -Exxx.
|
|
Hannes Reinecke |
cc93a0 |
+ **/
|
|
Hannes Reinecke |
cc93a0 |
+int
|
|
Hannes Reinecke |
cc93a0 |
+__lpfc_nvme_xmt_ls_rsp(struct lpfc_async_xchg_ctx *axchg,
|
|
Hannes Reinecke |
cc93a0 |
+ struct nvmefc_ls_rsp *ls_rsp,
|
|
Hannes Reinecke |
cc93a0 |
+ void (*xmt_ls_rsp_cmp)(struct lpfc_hba *phba,
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_iocbq *cmdwqe,
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_wcqe_complete *wcqe))
|
|
Hannes Reinecke |
cc93a0 |
{
|
|
Hannes Reinecke |
cc93a0 |
- struct lpfc_async_xchg_ctx *ctxp =
|
|
Hannes Reinecke |
cc93a0 |
- container_of(rsp, struct lpfc_async_xchg_ctx, ls_rsp);
|
|
Hannes Reinecke |
cc93a0 |
- struct lpfc_hba *phba = ctxp->phba;
|
|
Hannes Reinecke |
cc93a0 |
- struct hbq_dmabuf *nvmebuf =
|
|
Hannes Reinecke |
cc93a0 |
- (struct hbq_dmabuf *)ctxp->rqb_buffer;
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_hba *phba = axchg->phba;
|
|
Hannes Reinecke |
cc93a0 |
+ struct hbq_dmabuf *nvmebuf = (struct hbq_dmabuf *)axchg->rqb_buffer;
|
|
Hannes Reinecke |
cc93a0 |
struct lpfc_iocbq *nvmewqeq;
|
|
Hannes Reinecke |
cc93a0 |
- struct lpfc_nvmet_tgtport *nvmep = tgtport->private;
|
|
Hannes Reinecke |
cc93a0 |
struct lpfc_dmabuf dmabuf;
|
|
Hannes Reinecke |
cc93a0 |
struct ulp_bde64 bpl;
|
|
Hannes Reinecke |
cc93a0 |
int rc;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- if (phba->pport->load_flag & FC_UNLOADING)
|
|
Hannes Reinecke |
cc93a0 |
- return -ENODEV;
|
|
Hannes Reinecke |
cc93a0 |
-
|
|
Hannes Reinecke |
cc93a0 |
if (phba->pport->load_flag & FC_UNLOADING)
|
|
Hannes Reinecke |
cc93a0 |
return -ENODEV;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
lpfc_printf_log(phba, KERN_INFO, LOG_NVME_DISC,
|
|
Hannes Reinecke |
cc93a0 |
- "6023 NVMET LS rsp oxid x%x\n", ctxp->oxid);
|
|
Hannes Reinecke |
cc93a0 |
+ "6023 NVMEx LS rsp oxid x%x\n", axchg->oxid);
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- if ((ctxp->state != LPFC_NVME_STE_LS_RCV) ||
|
|
Hannes Reinecke |
cc93a0 |
- (ctxp->entry_cnt != 1)) {
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
|
|
Hannes Reinecke |
cc93a0 |
- "6412 NVMET LS rsp state mismatch "
|
|
Hannes Reinecke |
cc93a0 |
+ if (axchg->state != LPFC_NVME_STE_LS_RCV || axchg->entry_cnt != 1) {
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_printf_log(phba, KERN_ERR, LOG_NVME_DISC | LOG_NVME_IOERR,
|
|
Hannes Reinecke |
cc93a0 |
+ "6412 NVMEx LS rsp state mismatch "
|
|
Hannes Reinecke |
cc93a0 |
"oxid x%x: %d %d\n",
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->oxid, ctxp->state, ctxp->entry_cnt);
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->oxid, axchg->state, axchg->entry_cnt);
|
|
Hannes Reinecke |
cc93a0 |
+ return -EALREADY;
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->state = LPFC_NVME_STE_LS_RSP;
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->entry_cnt++;
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->state = LPFC_NVME_STE_LS_RSP;
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->entry_cnt++;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- nvmewqeq = lpfc_nvmet_prep_ls_wqe(phba, ctxp, rsp->rspdma,
|
|
Hannes Reinecke |
cc93a0 |
- rsp->rsplen);
|
|
Hannes Reinecke |
cc93a0 |
+ nvmewqeq = lpfc_nvmet_prep_ls_wqe(phba, axchg, ls_rsp->rspdma,
|
|
Hannes Reinecke |
cc93a0 |
+ ls_rsp->rsplen);
|
|
Hannes Reinecke |
cc93a0 |
if (nvmewqeq == NULL) {
|
|
Hannes Reinecke |
cc93a0 |
- atomic_inc(&nvmep->xmt_ls_drop);
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
|
|
Hannes Reinecke |
cc93a0 |
- "6150 LS Drop IO x%x: Prep\n",
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->oxid);
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_in_buf_free(phba, &nvmebuf->dbuf);
|
|
Hannes Reinecke |
cc93a0 |
- atomic_inc(&nvmep->xmt_ls_abort);
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_nvme_unsol_ls_issue_abort(phba, ctxp,
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->sid, ctxp->oxid);
|
|
Hannes Reinecke |
cc93a0 |
- return -ENOMEM;
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_printf_log(phba, KERN_ERR,
|
|
Hannes Reinecke |
cc93a0 |
+ LOG_NVME_DISC | LOG_NVME_IOERR | LOG_NVME_ABTS,
|
|
Hannes Reinecke |
cc93a0 |
+ "6150 NVMEx LS Drop Rsp x%x: Prep\n",
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->oxid);
|
|
Hannes Reinecke |
cc93a0 |
+ rc = -ENOMEM;
|
|
Hannes Reinecke |
cc93a0 |
+ goto out_free_buf;
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
/* Save numBdes for bpl2sgl */
|
|
Hannes Reinecke |
cc93a0 |
@@ -876,39 +908,106 @@ lpfc_nvmet_xmt_ls_rsp(struct nvmet_fc_target_port *tgtport,
|
|
Hannes Reinecke |
cc93a0 |
dmabuf.virt = &bpl;
|
|
Hannes Reinecke |
cc93a0 |
bpl.addrLow = nvmewqeq->wqe.xmit_sequence.bde.addrLow;
|
|
Hannes Reinecke |
cc93a0 |
bpl.addrHigh = nvmewqeq->wqe.xmit_sequence.bde.addrHigh;
|
|
Hannes Reinecke |
cc93a0 |
- bpl.tus.f.bdeSize = rsp->rsplen;
|
|
Hannes Reinecke |
cc93a0 |
+ bpl.tus.f.bdeSize = ls_rsp->rsplen;
|
|
Hannes Reinecke |
cc93a0 |
bpl.tus.f.bdeFlags = 0;
|
|
Hannes Reinecke |
cc93a0 |
bpl.tus.w = le32_to_cpu(bpl.tus.w);
|
|
Hannes Reinecke |
cc93a0 |
+ /*
|
|
Hannes Reinecke |
cc93a0 |
+ * Note: although we're using stack space for the dmabuf, the
|
|
Hannes Reinecke |
cc93a0 |
+ * call to lpfc_sli4_issue_wqe is synchronous, so it will not
|
|
Hannes Reinecke |
cc93a0 |
+ * be referenced after it returns back to this routine.
|
|
Hannes Reinecke |
cc93a0 |
+ */
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- nvmewqeq->wqe_cmpl = lpfc_nvmet_xmt_ls_rsp_cmp;
|
|
Hannes Reinecke |
cc93a0 |
+ nvmewqeq->wqe_cmpl = xmt_ls_rsp_cmp;
|
|
Hannes Reinecke |
cc93a0 |
nvmewqeq->iocb_cmpl = NULL;
|
|
Hannes Reinecke |
cc93a0 |
- nvmewqeq->context2 = ctxp;
|
|
Hannes Reinecke |
cc93a0 |
+ nvmewqeq->context2 = axchg;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_nvmeio_data(phba, "NVMET LS RESP: xri x%x wqidx x%x len x%x\n",
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->oxid, nvmewqeq->hba_wqidx, rsp->rsplen);
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_nvmeio_data(phba, "NVMEx LS RSP: xri x%x wqidx x%x len x%x\n",
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->oxid, nvmewqeq->hba_wqidx, ls_rsp->rsplen);
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ rc = lpfc_sli4_issue_wqe(phba, axchg->hdwq, nvmewqeq);
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ /* clear to be sure there's no reference */
|
|
Hannes Reinecke |
cc93a0 |
+ nvmewqeq->context3 = NULL;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
- rc = lpfc_sli4_issue_wqe(phba, ctxp->hdwq, nvmewqeq);
|
|
Hannes Reinecke |
cc93a0 |
if (rc == WQE_SUCCESS) {
|
|
Hannes Reinecke |
cc93a0 |
/*
|
|
Hannes Reinecke |
cc93a0 |
* Okay to repost buffer here, but wait till cmpl
|
|
Hannes Reinecke |
cc93a0 |
* before freeing ctxp and iocbq.
|
|
Hannes Reinecke |
cc93a0 |
*/
|
|
Hannes Reinecke |
cc93a0 |
lpfc_in_buf_free(phba, &nvmebuf->dbuf);
|
|
Hannes Reinecke |
cc93a0 |
- atomic_inc(&nvmep->xmt_ls_rsp);
|
|
Hannes Reinecke |
cc93a0 |
return 0;
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
- /* Give back resources */
|
|
Hannes Reinecke |
cc93a0 |
- atomic_inc(&nvmep->xmt_ls_drop);
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR,
|
|
Hannes Reinecke |
cc93a0 |
- "6151 LS Drop IO x%x: Issue %d\n",
|
|
Hannes Reinecke |
cc93a0 |
- ctxp->oxid, rc);
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_printf_log(phba, KERN_ERR,
|
|
Hannes Reinecke |
cc93a0 |
+ LOG_NVME_DISC | LOG_NVME_IOERR | LOG_NVME_ABTS,
|
|
Hannes Reinecke |
cc93a0 |
+ "6151 NVMEx LS RSP x%x: failed to transmit %d\n",
|
|
Hannes Reinecke |
cc93a0 |
+ axchg->oxid, rc);
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ rc = -ENXIO;
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
lpfc_nlp_put(nvmewqeq->context1);
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
+out_free_buf:
|
|
Hannes Reinecke |
cc93a0 |
+ /* Give back resources */
|
|
Hannes Reinecke |
cc93a0 |
lpfc_in_buf_free(phba, &nvmebuf->dbuf);
|
|
Hannes Reinecke |
cc93a0 |
- atomic_inc(&nvmep->xmt_ls_abort);
|
|
Hannes Reinecke |
cc93a0 |
- lpfc_nvme_unsol_ls_issue_abort(phba, ctxp, ctxp->sid, ctxp->oxid);
|
|
Hannes Reinecke |
cc93a0 |
- return -ENXIO;
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ /*
|
|
Hannes Reinecke |
cc93a0 |
+ * As transport doesn't track completions of responses, if the rsp
|
|
Hannes Reinecke |
cc93a0 |
+ * fails to send, the transport will effectively ignore the rsp
|
|
Hannes Reinecke |
cc93a0 |
+ * and consider the LS done. However, the driver has an active
|
|
Hannes Reinecke |
cc93a0 |
+ * exchange open for the LS - so be sure to abort the exchange
|
|
Hannes Reinecke |
cc93a0 |
+ * if the response isn't sent.
|
|
Hannes Reinecke |
cc93a0 |
+ */
|
|
Hannes Reinecke |
cc93a0 |
+ lpfc_nvme_unsol_ls_issue_abort(phba, axchg, axchg->sid, axchg->oxid);
|
|
Hannes Reinecke |
cc93a0 |
+ return rc;
|
|
Hannes Reinecke |
cc93a0 |
+}
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+/**
|
|
Hannes Reinecke |
cc93a0 |
+ * lpfc_nvmet_xmt_ls_rsp - Transmit NVME LS response
|
|
Hannes Reinecke |
cc93a0 |
+ * @tgtport: pointer to target port that NVME LS is to be transmit from.
|
|
Hannes Reinecke |
cc93a0 |
+ * @ls_rsp: pointer to the transport LS RSP that is to be sent
|
|
Hannes Reinecke |
cc93a0 |
+ *
|
|
Hannes Reinecke |
cc93a0 |
+ * Driver registers this routine to transmit responses for received NVME
|
|
Hannes Reinecke |
cc93a0 |
+ * LS requests.
|
|
Hannes Reinecke |
cc93a0 |
+ *
|
|
Hannes Reinecke |
cc93a0 |
+ * This routine is used to format and send a WQE to transmit a NVME LS
|
|
Hannes Reinecke |
cc93a0 |
+ * Response. The ls_rsp is used to reverse-map the LS to the original
|
|
Hannes Reinecke |
cc93a0 |
+ * NVME LS request sequence, which provides addressing information for
|
|
Hannes Reinecke |
cc93a0 |
+ * the remote port the LS to be sent to, as well as the exchange id
|
|
Hannes Reinecke |
cc93a0 |
+ * that is the LS is bound to.
|
|
Hannes Reinecke |
cc93a0 |
+ *
|
|
Hannes Reinecke |
cc93a0 |
+ * Returns:
|
|
Hannes Reinecke |
cc93a0 |
+ * 0 : if response successfully transmit
|
|
Hannes Reinecke |
cc93a0 |
+ * non-zero : if response failed to transmit, of the form -Exxx.
|
|
Hannes Reinecke |
cc93a0 |
+ **/
|
|
Hannes Reinecke |
cc93a0 |
+static int
|
|
Hannes Reinecke |
cc93a0 |
+lpfc_nvmet_xmt_ls_rsp(struct nvmet_fc_target_port *tgtport,
|
|
Hannes Reinecke |
cc93a0 |
+ struct nvmefc_ls_rsp *ls_rsp)
|
|
Hannes Reinecke |
cc93a0 |
+{
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_async_xchg_ctx *axchg =
|
|
Hannes Reinecke |
cc93a0 |
+ container_of(ls_rsp, struct lpfc_async_xchg_ctx, ls_rsp);
|
|
Hannes Reinecke |
cc93a0 |
+ struct lpfc_nvmet_tgtport *nvmep = tgtport->private;
|
|
Hannes Reinecke |
cc93a0 |
+ int rc;
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ if (axchg->phba->pport->load_flag & FC_UNLOADING)
|
|
Hannes Reinecke |
cc93a0 |
+ return -ENODEV;
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ rc = __lpfc_nvme_xmt_ls_rsp(axchg, ls_rsp, lpfc_nvmet_xmt_ls_rsp_cmp);
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ if (rc) {
|
|
Hannes Reinecke |
cc93a0 |
+ atomic_inc(&nvmep->xmt_ls_drop);
|
|
Hannes Reinecke |
cc93a0 |
+ /*
|
|
Hannes Reinecke |
cc93a0 |
+ * unless the failure is due to having already sent
|
|
Hannes Reinecke |
cc93a0 |
+ * the response, an abort will be generated for the
|
|
Hannes Reinecke |
cc93a0 |
+ * exchange if the rsp can't be sent.
|
|
Hannes Reinecke |
cc93a0 |
+ */
|
|
Hannes Reinecke |
cc93a0 |
+ if (rc != -EALREADY)
|
|
Hannes Reinecke |
cc93a0 |
+ atomic_inc(&nvmep->xmt_ls_abort);
|
|
Hannes Reinecke |
cc93a0 |
+ return rc;
|
|
Hannes Reinecke |
cc93a0 |
+ }
|
|
Hannes Reinecke |
cc93a0 |
+
|
|
Hannes Reinecke |
cc93a0 |
+ atomic_inc(&nvmep->xmt_ls_rsp);
|
|
Hannes Reinecke |
cc93a0 |
+ return 0;
|
|
Hannes Reinecke |
cc93a0 |
}
|
|
Hannes Reinecke |
cc93a0 |
|
|
Hannes Reinecke |
cc93a0 |
static int
|
|
Hannes Reinecke |
cc93a0 |
--
|
|
Hannes Reinecke |
cc93a0 |
2.16.4
|
|
Hannes Reinecke |
cc93a0 |
|