scsi: lpfc: NVME Initiator: Merge into FC discovery
NVME Initiator: Merge into FC discovery Adds NVME PRLI support and Nameserver registrations and Queries for NVME Signed-off-by: Dick Kennedy <dick.kennedy@broadcom.com> Signed-off-by: James Smart <james.smart@broadcom.com> Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:

committed by
Martin K. Petersen

parent
895427bd01
commit
a0f2d3ef37
@@ -31,6 +31,9 @@
|
||||
#include <scsi/scsi_device.h>
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <scsi/scsi_transport_fc.h>
|
||||
#include <scsi/fc/fc_fs.h>
|
||||
|
||||
#include <linux/nvme-fc-driver.h>
|
||||
|
||||
#include "lpfc_hw4.h"
|
||||
#include "lpfc_hw.h"
|
||||
@@ -38,8 +41,9 @@
|
||||
#include "lpfc_disc.h"
|
||||
#include "lpfc_sli.h"
|
||||
#include "lpfc_sli4.h"
|
||||
#include "lpfc_scsi.h"
|
||||
#include "lpfc.h"
|
||||
#include "lpfc_scsi.h"
|
||||
#include "lpfc_nvme.h"
|
||||
#include "lpfc_logmsg.h"
|
||||
#include "lpfc_crtn.h"
|
||||
#include "lpfc_vport.h"
|
||||
@@ -853,9 +857,12 @@ lpfc_port_link_failure(struct lpfc_vport *vport)
|
||||
void
|
||||
lpfc_linkdown_port(struct lpfc_vport *vport)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
|
||||
fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKDOWN, 0);
|
||||
if (phba->cfg_enable_fc4_type != LPFC_ENABLE_NVME)
|
||||
fc_host_post_event(shost, fc_get_event_number(),
|
||||
FCH_EVT_LINKDOWN, 0);
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||
"Link Down: state:x%x rtry:x%x flg:x%x",
|
||||
@@ -981,7 +988,9 @@ lpfc_linkup_port(struct lpfc_vport *vport)
|
||||
(vport != phba->pport))
|
||||
return;
|
||||
|
||||
fc_host_post_event(shost, fc_get_event_number(), FCH_EVT_LINKUP, 0);
|
||||
if (phba->cfg_enable_fc4_type != LPFC_ENABLE_NVME)
|
||||
fc_host_post_event(shost, fc_get_event_number(),
|
||||
FCH_EVT_LINKUP, 0);
|
||||
|
||||
spin_lock_irq(shost->host_lock);
|
||||
vport->fc_flag &= ~(FC_PT2PT | FC_PT2PT_PLOGI | FC_ABORT_DISCOVERY |
|
||||
@@ -3570,6 +3579,8 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
|
||||
spin_unlock_irq(shost->host_lock);
|
||||
vport->fc_myDID = 0;
|
||||
|
||||
/* todo: init: revise localport nvme attributes */
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -3819,6 +3830,52 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine will issue a GID_FT for each FC4 Type supported
|
||||
* by the driver. ALL GID_FTs must complete before discovery is started.
|
||||
*/
|
||||
int
|
||||
lpfc_issue_gidft(struct lpfc_vport *vport)
|
||||
{
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
|
||||
/* Good status, issue CT Request to NameServer */
|
||||
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_FCP)) {
|
||||
if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, SLI_CTPT_FCP)) {
|
||||
/* Cannot issue NameServer FCP Query, so finish up
|
||||
* discovery
|
||||
*/
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_SLI,
|
||||
"0604 %s FC TYPE %x %s\n",
|
||||
"Failed to issue GID_FT to ",
|
||||
FC_TYPE_FCP,
|
||||
"Finishing discovery.");
|
||||
return 0;
|
||||
}
|
||||
vport->gidft_inp++;
|
||||
}
|
||||
|
||||
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
|
||||
if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, SLI_CTPT_NVME)) {
|
||||
/* Cannot issue NameServer NVME Query, so finish up
|
||||
* discovery
|
||||
*/
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_SLI,
|
||||
"0605 %s FC_TYPE %x %s %d\n",
|
||||
"Failed to issue GID_FT to ",
|
||||
FC_TYPE_NVME,
|
||||
"Finishing discovery: gidftinp ",
|
||||
vport->gidft_inp);
|
||||
if (vport->gidft_inp == 0)
|
||||
return 0;
|
||||
} else
|
||||
vport->gidft_inp++;
|
||||
}
|
||||
return vport->gidft_inp;
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine handles processing a NameServer REG_LOGIN mailbox
|
||||
* command upon completion. It is setup in the LPFC_MBOXQ
|
||||
@@ -3835,12 +3892,14 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
||||
|
||||
pmb->context1 = NULL;
|
||||
pmb->context2 = NULL;
|
||||
vport->gidft_inp = 0;
|
||||
|
||||
if (mb->mbxStatus) {
|
||||
out:
|
||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
|
||||
"0260 Register NameServer error: 0x%x\n",
|
||||
mb->mbxStatus);
|
||||
|
||||
out:
|
||||
/* decrement the node reference count held for this
|
||||
* callback function.
|
||||
*/
|
||||
@@ -3884,20 +3943,28 @@ out:
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RSNN_NN, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RSPN_ID, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RFT_ID, 0, 0);
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, 0);
|
||||
|
||||
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_FCP))
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, FC_TYPE_FCP);
|
||||
|
||||
if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME))
|
||||
lpfc_ns_cmd(vport, SLI_CTNS_RFF_ID, 0, FC_TYPE_NVME);
|
||||
|
||||
/* Issue SCR just before NameServer GID_FT Query */
|
||||
lpfc_issue_els_scr(vport, SCR_DID, 0);
|
||||
}
|
||||
|
||||
vport->fc_ns_retry = 0;
|
||||
/* Good status, issue CT Request to NameServer */
|
||||
if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0)) {
|
||||
/* Cannot issue NameServer Query, so finish up discovery */
|
||||
if (lpfc_issue_gidft(vport) == 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* decrement the node reference count held for this
|
||||
/*
|
||||
* At this point in time we may need to wait for multiple
|
||||
* SLI_CTNS_GID_FT CT commands to complete before we start discovery.
|
||||
*
|
||||
* decrement the node reference count held for this
|
||||
* callback function.
|
||||
*/
|
||||
lpfc_nlp_put(ndlp);
|
||||
@@ -3990,6 +4057,10 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp)
|
||||
{
|
||||
struct fc_rport *rport = ndlp->rport;
|
||||
struct lpfc_vport *vport = ndlp->vport;
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
|
||||
if (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)
|
||||
return;
|
||||
|
||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
|
||||
"rport delete: did:x%x flg:x%x type x%x",
|
||||
@@ -4047,6 +4118,7 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
int old_state, int new_state)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_hba *phba = vport->phba;
|
||||
|
||||
if (new_state == NLP_STE_UNMAPPED_NODE) {
|
||||
ndlp->nlp_flag &= ~NLP_NODEV_REMOVE;
|
||||
@@ -4057,23 +4129,51 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
if (new_state == NLP_STE_NPR_NODE)
|
||||
ndlp->nlp_flag &= ~NLP_RCV_PLOGI;
|
||||
|
||||
/* Transport interface */
|
||||
if (ndlp->rport && (old_state == NLP_STE_MAPPED_NODE ||
|
||||
old_state == NLP_STE_UNMAPPED_NODE)) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
lpfc_unregister_remote_port(ndlp);
|
||||
/* FCP and NVME Transport interface */
|
||||
if ((old_state == NLP_STE_MAPPED_NODE ||
|
||||
old_state == NLP_STE_UNMAPPED_NODE)) {
|
||||
if (ndlp->rport) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
lpfc_unregister_remote_port(ndlp);
|
||||
}
|
||||
|
||||
/* Notify the NVME transport of this rport's loss */
|
||||
if (((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
|
||||
(phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) &&
|
||||
(vport->phba->nvmet_support == 0) &&
|
||||
((ndlp->nlp_fc4_type & NLP_FC4_NVME) ||
|
||||
(ndlp->nlp_DID == Fabric_DID))) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
/* todo: init: unregister rport from nvme */
|
||||
}
|
||||
}
|
||||
|
||||
/* FCP and NVME Transport interfaces */
|
||||
|
||||
if (new_state == NLP_STE_MAPPED_NODE ||
|
||||
new_state == NLP_STE_UNMAPPED_NODE) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
/*
|
||||
* Tell the fc transport about the port, if we haven't
|
||||
* already. If we have, and it's a scsi entity, be
|
||||
* sure to unblock any attached scsi devices
|
||||
*/
|
||||
lpfc_register_remote_port(vport, ndlp);
|
||||
if ((ndlp->nlp_fc4_type & NLP_FC4_FCP) ||
|
||||
(ndlp->nlp_DID == Fabric_DID)) {
|
||||
vport->phba->nport_event_cnt++;
|
||||
/*
|
||||
* Tell the fc transport about the port, if we haven't
|
||||
* already. If we have, and it's a scsi entity, be
|
||||
*/
|
||||
lpfc_register_remote_port(vport, ndlp);
|
||||
}
|
||||
/* Notify the NVME transport of this new rport. */
|
||||
if (ndlp->nlp_fc4_type & NLP_FC4_NVME) {
|
||||
if (vport->phba->nvmet_support == 0) {
|
||||
/* Register this rport with the transport.
|
||||
* Initiators take the NDLP ref count in
|
||||
* the register.
|
||||
*/
|
||||
vport->phba->nport_event_cnt++;
|
||||
/* todo: init: register rport with nvme */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((new_state == NLP_STE_MAPPED_NODE) &&
|
||||
(vport->stat_data_enabled)) {
|
||||
/*
|
||||
@@ -4091,12 +4191,13 @@ lpfc_nlp_state_cleanup(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
"0x%x\n", ndlp->nlp_DID);
|
||||
}
|
||||
/*
|
||||
* if we added to Mapped list, but the remote port
|
||||
* registration failed or assigned a target id outside
|
||||
* our presentable range - move the node to the
|
||||
* Unmapped List
|
||||
* If the node just added to Mapped list was an FCP target,
|
||||
* but the remote port registration failed or assigned a target
|
||||
* id outside the presentable range - move the node to the
|
||||
* Unmapped List.
|
||||
*/
|
||||
if (new_state == NLP_STE_MAPPED_NODE &&
|
||||
if ((new_state == NLP_STE_MAPPED_NODE) &&
|
||||
(ndlp->nlp_type & NLP_FCP_TARGET) &&
|
||||
(!ndlp->rport ||
|
||||
ndlp->rport->scsi_target_id == -1 ||
|
||||
ndlp->rport->scsi_target_id >= LPFC_MAX_TARGET)) {
|
||||
@@ -4230,6 +4331,7 @@ lpfc_initialize_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
ndlp->vport = vport;
|
||||
ndlp->phba = vport->phba;
|
||||
ndlp->nlp_sid = NLP_NO_SID;
|
||||
ndlp->nlp_fc4_type = NLP_FC4_NONE;
|
||||
kref_init(&ndlp->kref);
|
||||
NLP_INT_NODE_ACT(ndlp);
|
||||
atomic_set(&ndlp->cmd_pending, 0);
|
||||
@@ -5369,12 +5471,13 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
||||
switch (vport->port_state) {
|
||||
|
||||
case LPFC_LOCAL_CFG_LINK:
|
||||
/* port_state is identically LPFC_LOCAL_CFG_LINK while waiting for
|
||||
* FAN
|
||||
*/
|
||||
/* FAN timeout */
|
||||
/*
|
||||
* port_state is identically LPFC_LOCAL_CFG_LINK while
|
||||
* waiting for FAN timeout
|
||||
*/
|
||||
lpfc_printf_vlog(vport, KERN_WARNING, LOG_DISCOVERY,
|
||||
"0221 FAN timeout\n");
|
||||
|
||||
/* Start discovery by sending FLOGI, clean up old rpis */
|
||||
list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
|
||||
nlp_listp) {
|
||||
@@ -5445,8 +5548,8 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
|
||||
if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
|
||||
/* Try it one more time */
|
||||
vport->fc_ns_retry++;
|
||||
rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
|
||||
vport->fc_ns_retry, 0);
|
||||
vport->gidft_inp = 0;
|
||||
rc = lpfc_issue_gidft(vport);
|
||||
if (rc == 0)
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user