[PATCH v2 14/18] lpfc: NVME Target: Merge into FC discovery
James Smart
jsmart2021 at gmail.com
Mon Feb 6 15:09:04 PST 2017
NVME Target: Merge into FC discovery
Adds NVME PRLI handling and Nameserver registrations for NVME
Signed-off-by: Dick Kennedy <dick.kennedy at broadcom.com>
Signed-off-by: James Smart <james.smart at broadcom.com>
---
Modifications in V2:
Bug fix in reglogin
drivers/scsi/lpfc/lpfc_ct.c | 8 +++++++-
drivers/scsi/lpfc/lpfc_els.c | 34 ++++++++++++++++++++++++++++++----
drivers/scsi/lpfc/lpfc_hbadisc.c | 27 +++++++++++++++++++++++----
drivers/scsi/lpfc/lpfc_nportdisc.c | 35 ++++++++++++++++++++++++++++++++---
4 files changed, 92 insertions(+), 12 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 2c051369..d576da4 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -1433,7 +1433,13 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode,
if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) &&
(context == FC_TYPE_NVME)) {
- lpfc_nvme_update_localport(vport);
+ if ((vport == phba->pport) && phba->nvmet_support) {
+ CtReq->un.rff.fbits = (FC4_FEATURE_TARGET |
+ FC4_FEATURE_NVME_DISC);
+ /* todo: update targetport attributes */
+ } else {
+ lpfc_nvme_update_localport(vport);
+ }
CtReq->un.rff.type_code = context;
} else if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 1155f01..b7927c2 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -2211,7 +2211,13 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
!phba->nvmet_support)
bf_set(prli_fba, npr_nvme, 1);
- bf_set(prli_init, npr_nvme, 1);
+ if (phba->nvmet_support) {
+ bf_set(prli_tgt, npr_nvme, 1);
+ bf_set(prli_disc, npr_nvme, 1);
+
+ } else {
+ bf_set(prli_init, npr_nvme, 1);
+ }
npr_nvme->word1 = cpu_to_be32(npr_nvme->word1);
npr_nvme->word4 = cpu_to_be32(npr_nvme->word4);
elsiocb->iocb_flag |= LPFC_PRLI_NVME_REQ;
@@ -2623,8 +2629,11 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
phba->pport->fc_myDID = 0;
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
- (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
- lpfc_nvme_update_localport(phba->pport);
+ (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
+ if (!phba->nvmet_support)
+ lpfc_nvme_update_localport(phba->pport);
+ /* todo: tgt: update targetport attributes */
+ }
mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
if (mbox) {
@@ -4405,7 +4414,22 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
bf_set(prli_type_code, npr_nvme, PRLI_NVME_TYPE);
bf_set(prli_estabImagePair, npr_nvme, 0); /* Should be 0 */
bf_set(prli_acc_rsp_code, npr_nvme, PRLI_REQ_EXECUTED);
- bf_set(prli_init, npr_nvme, 1);
+ if (phba->nvmet_support) {
+ bf_set(prli_tgt, npr_nvme, 1);
+ bf_set(prli_disc, npr_nvme, 1);
+ if (phba->cfg_nvme_enable_fb) {
+ bf_set(prli_fba, npr_nvme, 1);
+
+ /* TBD. Target mode needs to post buffers
+ * that support the configured first burst
+ * byte size.
+ */
+ bf_set(prli_fb_sz, npr_nvme,
+ phba->cfg_nvmet_fb_size);
+ }
+ } else {
+ bf_set(prli_init, npr_nvme, 1);
+ }
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
"6015 NVME issue PRLI ACC word1 x%08x "
@@ -5823,6 +5847,8 @@ lpfc_rscn_recovery_check(struct lpfc_vport *vport)
(ndlp->nlp_state == NLP_STE_UNUSED_NODE) ||
!lpfc_rscn_payload_check(vport, ndlp->nlp_DID))
continue;
+ if (vport->phba->nvmet_support)
+ continue;
lpfc_disc_state_machine(vport, ndlp, NULL,
NLP_EVT_DEVICE_RECOVERY);
lpfc_cancel_retry_delay_tmo(vport, ndlp);
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 8c000e4..f8e0c0e 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -910,8 +910,11 @@ lpfc_linkdown(struct lpfc_hba *phba)
vports[i]->fc_myDID = 0;
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
- (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
- lpfc_nvme_update_localport(vports[i]);
+ (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
+ if (!phba->nvmet_support)
+ lpfc_nvme_update_localport(vports[i]);
+ /* todo: tgt: update targetport attributes */
+ }
}
}
lpfc_destroy_vport_work_array(phba, vports);
@@ -3583,8 +3586,11 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
vport->fc_myDID = 0;
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
- (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
- lpfc_nvme_update_localport(vport);
+ (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
+ if (!phba->nvmet_support)
+ lpfc_nvme_update_localport(vport);
+ /* todo: update targetport attributes */
+ }
goto out;
}
@@ -4175,6 +4181,11 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
*/
vport->phba->nport_event_cnt++;
lpfc_nvme_register_port(vport, ndlp);
+ } else {
+ /* Just take an NDLP ref count since the
+ * target does not register rports.
+ */
+ lpfc_nlp_get(ndlp);
}
}
}
@@ -5096,6 +5107,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
return NULL;
lpfc_nlp_init(vport, ndlp, did);
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+ if (vport->phba->nvmet_support)
+ return ndlp;
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_NPR_2B_DISC;
spin_unlock_irq(shost->host_lock);
@@ -5104,6 +5117,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_NPR_NODE);
if (!ndlp)
return NULL;
+ if (vport->phba->nvmet_support)
+ return ndlp;
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_NPR_2B_DISC;
spin_unlock_irq(shost->host_lock);
@@ -5123,6 +5138,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
* delay timeout is not needed.
*/
lpfc_cancel_retry_delay_tmo(vport, ndlp);
+ if (vport->phba->nvmet_support)
+ return ndlp;
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_NPR_2B_DISC;
spin_unlock_irq(shost->host_lock);
@@ -5138,6 +5155,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
ndlp->nlp_flag & NLP_RCV_PLOGI)
return NULL;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+ if (vport->phba->nvmet_support)
+ return ndlp;
spin_lock_irq(shost->host_lock);
ndlp->nlp_flag |= NLP_NPR_2B_DISC;
spin_unlock_irq(shost->host_lock);
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 16bd425..5203bfd 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -754,6 +754,14 @@ lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
}
if (npr->Retry)
ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
+
+ /* If this driver is in nvme target mode, set the ndlp's fc4
+ * type to NVME provided the PRLI response claims NVME FC4
+ * type. Target mode does not issue gft_id so doesn't get
+ * the fc4 type set until now.
+ */
+ if ((phba->nvmet_support) && (npr->prliType == PRLI_NVME_TYPE))
+ ndlp->nlp_fc4_type |= NLP_FC4_NVME;
}
if (rport) {
/* We need to update the rport role values */
@@ -1526,8 +1534,17 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
{
struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
- /* Initiator mode. */
- lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
+ if (vport->phba->nvmet_support) {
+ /* NVME Target mode. Handle and respond to the PRLI and
+ * transition to UNMAPPED.
+ */
+ lpfc_rcv_prli(vport, ndlp, cmdiocb);
+ lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
+ } else {
+ /* Initiator mode. */
+ lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
+ }
return ndlp->nlp_state;
}
@@ -1689,7 +1706,12 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
lpfc_issue_els_prli(vport, ndlp, 0);
} else {
- /* Only Fabric ports should transition */
+ if ((vport->fc_flag & FC_PT2PT) && phba->nvmet_support)
+ phba->targetport->port_id = vport->fc_myDID;
+
+ /* Only Fabric ports should transition. NVME target
+ * must complete PRLI.
+ */
if (ndlp->nlp_type & NLP_FABRIC) {
ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
@@ -1735,6 +1757,13 @@ lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
spin_lock_irq(shost->host_lock);
+ /* If we are a target we won't immediately transition into PRLI,
+ * so if REG_LOGIN already completed we don't need to ignore it.
+ */
+ if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED) ||
+ !vport->phba->nvmet_support)
+ ndlp->nlp_flag |= NLP_IGNR_REG_CMPL;
+
ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
spin_unlock_irq(shost->host_lock);
lpfc_disc_set_adisc(vport, ndlp);
--
2.5.0
More information about the Linux-nvme
mailing list