|
Daniel Wagner |
499c09 |
From: James Smart <jsmart2021@gmail.com>
|
|
Daniel Wagner |
499c09 |
Date: Fri, 14 May 2021 12:55:54 -0700
|
|
Daniel Wagner |
499c09 |
Subject: scsi: lpfc: Fix node handling for Fabric Controller and Domain
|
|
Daniel Wagner |
499c09 |
Controller
|
|
Daniel Wagner |
499c09 |
Patch-mainline: Queued in subsystem maintainer repository
|
|
Daniel Wagner |
499c09 |
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git
|
|
Daniel Wagner |
499c09 |
Git-commit: fe83e3b9b422ac8ece2359c7b7290efe7f0335a2
|
|
Daniel Wagner |
499c09 |
References: bsc#1186452
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
During link bounce testing, RPI counts were seen to differ from the number
|
|
Daniel Wagner |
499c09 |
of nodes. For fabric and domain controllers, a temporary RPI is assigned,
|
|
Daniel Wagner |
499c09 |
but the code isn't registering it. If the nodes do go away, such as on link
|
|
Daniel Wagner |
499c09 |
down, the temporary RPI isn't being released.
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
Change the way these two fabric services are managed, make them behave like
|
|
Daniel Wagner |
499c09 |
any other remote port. Register the RPI and register with the transport.
|
|
Daniel Wagner |
499c09 |
Never leave the nodes in a NPR or UNUSED state where their RPI is in limbo.
|
|
Daniel Wagner |
499c09 |
This allows them to follow normal dev_loss_tmo handling, RPI refcounting,
|
|
Daniel Wagner |
499c09 |
and normal removal rules. It also allows fabric I/Os to use the RPI for
|
|
Daniel Wagner |
499c09 |
traffic requests.
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
Note: There is some logic that still has a couple of exceptions when the
|
|
Daniel Wagner |
499c09 |
Domain controller (0xfffcXX). There are cases where the fabric won't have a
|
|
Daniel Wagner |
499c09 |
valid login but will send RDP. Other times, it will it send a LOGO then an
|
|
Daniel Wagner |
499c09 |
RDP. It makes for ad-hoc behavior to manage the node. Exceptions are
|
|
Daniel Wagner |
499c09 |
documented in the code.
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
Link: https://lore.kernel.org/r/20210514195559.119853-7-jsmart2021@gmail.com
|
|
Daniel Wagner |
499c09 |
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
|
|
Daniel Wagner |
499c09 |
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
|
|
Daniel Wagner |
499c09 |
Signed-off-by: James Smart <jsmart2021@gmail.com>
|
|
Daniel Wagner |
499c09 |
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
Daniel Wagner |
499c09 |
[dwagner: context update in lpfc_rcv_logo]
|
|
Daniel Wagner |
499c09 |
Acked-by: Daniel Wagner <dwagner@suse.de>
|
|
Daniel Wagner |
499c09 |
---
|
|
Daniel Wagner |
499c09 |
drivers/scsi/lpfc/lpfc_crtn.h | 1
|
|
Daniel Wagner |
499c09 |
drivers/scsi/lpfc/lpfc_debugfs.c | 4 -
|
|
Daniel Wagner |
499c09 |
drivers/scsi/lpfc/lpfc_disc.h | 1
|
|
Daniel Wagner |
499c09 |
drivers/scsi/lpfc/lpfc_els.c | 137 +++++++++++++++++++++++++++++++++----
|
|
Daniel Wagner |
499c09 |
drivers/scsi/lpfc/lpfc_hbadisc.c | 54 +++++++++++++-
|
|
Daniel Wagner |
499c09 |
drivers/scsi/lpfc/lpfc_nportdisc.c | 12 +++
|
|
Daniel Wagner |
499c09 |
drivers/scsi/lpfc/lpfc_sli.c | 1
|
|
Daniel Wagner |
499c09 |
7 files changed, 190 insertions(+), 20 deletions(-)
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
--- a/drivers/scsi/lpfc/lpfc_crtn.h
|
|
Daniel Wagner |
499c09 |
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
|
|
Daniel Wagner |
499c09 |
@@ -81,6 +81,7 @@ void lpfc_mbx_cmpl_reg_login(struct lpfc
|
|
Daniel Wagner |
499c09 |
void lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
|
Daniel Wagner |
499c09 |
void lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
|
Daniel Wagner |
499c09 |
void lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
|
Daniel Wagner |
499c09 |
+void lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb);
|
|
Daniel Wagner |
499c09 |
void lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
|
Daniel Wagner |
499c09 |
void lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
|
Daniel Wagner |
499c09 |
void lpfc_unregister_vfi_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *);
|
|
Daniel Wagner |
499c09 |
--- a/drivers/scsi/lpfc/lpfc_debugfs.c
|
|
Daniel Wagner |
499c09 |
+++ b/drivers/scsi/lpfc/lpfc_debugfs.c
|
|
Daniel Wagner |
499c09 |
@@ -866,10 +866,10 @@ lpfc_debugfs_nodelist_data(struct lpfc_v
|
|
Daniel Wagner |
499c09 |
len += scnprintf(buf+len, size-len, "%s DID:x%06x ",
|
|
Daniel Wagner |
499c09 |
statep, ndlp->nlp_DID);
|
|
Daniel Wagner |
499c09 |
len += scnprintf(buf+len, size-len,
|
|
Daniel Wagner |
499c09 |
- "WWPN x%llx ",
|
|
Daniel Wagner |
499c09 |
+ "WWPN x%016llx ",
|
|
Daniel Wagner |
499c09 |
wwn_to_u64(ndlp->nlp_portname.u.wwn));
|
|
Daniel Wagner |
499c09 |
len += scnprintf(buf+len, size-len,
|
|
Daniel Wagner |
499c09 |
- "WWNN x%llx ",
|
|
Daniel Wagner |
499c09 |
+ "WWNN x%016llx ",
|
|
Daniel Wagner |
499c09 |
wwn_to_u64(ndlp->nlp_nodename.u.wwn));
|
|
Daniel Wagner |
499c09 |
len += scnprintf(buf+len, size-len, "RPI:x%04x ",
|
|
Daniel Wagner |
499c09 |
ndlp->nlp_rpi);
|
|
Daniel Wagner |
499c09 |
--- a/drivers/scsi/lpfc/lpfc_disc.h
|
|
Daniel Wagner |
499c09 |
+++ b/drivers/scsi/lpfc/lpfc_disc.h
|
|
Daniel Wagner |
499c09 |
@@ -79,6 +79,7 @@ struct lpfc_node_rrqs {
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
struct lpfc_nodelist {
|
|
Daniel Wagner |
499c09 |
struct list_head nlp_listp;
|
|
Daniel Wagner |
499c09 |
+ struct serv_parm fc_sparam; /* buffer for service params */
|
|
Daniel Wagner |
499c09 |
struct lpfc_name nlp_portname;
|
|
Daniel Wagner |
499c09 |
struct lpfc_name nlp_nodename;
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
--- a/drivers/scsi/lpfc/lpfc_els.c
|
|
Daniel Wagner |
499c09 |
+++ b/drivers/scsi/lpfc/lpfc_els.c
|
|
Daniel Wagner |
499c09 |
@@ -3086,6 +3086,95 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba,
|
|
Daniel Wagner |
499c09 |
}
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
/**
|
|
Daniel Wagner |
499c09 |
+ * lpfc_reg_fab_ctrl_node - RPI register the fabric controller node.
|
|
Daniel Wagner |
499c09 |
+ * @vport: pointer to lpfc_vport data structure.
|
|
Daniel Wagner |
499c09 |
+ * @fc_ndlp: pointer to the fabric controller (0xfffffd) node.
|
|
Daniel Wagner |
499c09 |
+ *
|
|
Daniel Wagner |
499c09 |
+ * This routine registers the rpi assigned to the fabric controller
|
|
Daniel Wagner |
499c09 |
+ * NPort_ID (0xfffffd) with the port and moves the node to UNMAPPED
|
|
Daniel Wagner |
499c09 |
+ * state triggering a registration with the SCSI transport.
|
|
Daniel Wagner |
499c09 |
+ *
|
|
Daniel Wagner |
499c09 |
+ * This routine is single out because the fabric controller node
|
|
Daniel Wagner |
499c09 |
+ * does not receive a PLOGI. This routine is consumed by the
|
|
Daniel Wagner |
499c09 |
+ * SCR and RDF ELS commands. Callers are expected to qualify
|
|
Daniel Wagner |
499c09 |
+ * with SLI4 first.
|
|
Daniel Wagner |
499c09 |
+ **/
|
|
Daniel Wagner |
499c09 |
+static int
|
|
Daniel Wagner |
499c09 |
+lpfc_reg_fab_ctrl_node(struct lpfc_vport *vport, struct lpfc_nodelist *fc_ndlp)
|
|
Daniel Wagner |
499c09 |
+{
|
|
Daniel Wagner |
499c09 |
+ int rc = 0;
|
|
Daniel Wagner |
499c09 |
+ struct lpfc_hba *phba = vport->phba;
|
|
Daniel Wagner |
499c09 |
+ struct lpfc_nodelist *ns_ndlp;
|
|
Daniel Wagner |
499c09 |
+ LPFC_MBOXQ_t *mbox;
|
|
Daniel Wagner |
499c09 |
+ struct lpfc_dmabuf *mp;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ if (fc_ndlp->nlp_flag & NLP_RPI_REGISTERED)
|
|
Daniel Wagner |
499c09 |
+ return rc;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ ns_ndlp = lpfc_findnode_did(vport, NameServer_DID);
|
|
Daniel Wagner |
499c09 |
+ if (!ns_ndlp)
|
|
Daniel Wagner |
499c09 |
+ return -ENODEV;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
|
|
Daniel Wagner |
499c09 |
+ "0935 %s: Reg FC RPI x%x on FC DID x%x NSSte: x%x\n",
|
|
Daniel Wagner |
499c09 |
+ __func__, fc_ndlp->nlp_rpi, fc_ndlp->nlp_DID,
|
|
Daniel Wagner |
499c09 |
+ ns_ndlp->nlp_state);
|
|
Daniel Wagner |
499c09 |
+ if (ns_ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)
|
|
Daniel Wagner |
499c09 |
+ return -ENODEV;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
|
|
Daniel Wagner |
499c09 |
+ if (!mbox) {
|
|
Daniel Wagner |
499c09 |
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
|
|
Daniel Wagner |
499c09 |
+ "0936 %s: no memory for reg_login "
|
|
Daniel Wagner |
499c09 |
+ "Data: x%x x%x x%x x%x\n", __func__,
|
|
Daniel Wagner |
499c09 |
+ fc_ndlp->nlp_DID, fc_ndlp->nlp_state,
|
|
Daniel Wagner |
499c09 |
+ fc_ndlp->nlp_flag, fc_ndlp->nlp_rpi);
|
|
Daniel Wagner |
499c09 |
+ return -ENOMEM;
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
+ rc = lpfc_reg_rpi(phba, vport->vpi, fc_ndlp->nlp_DID,
|
|
Daniel Wagner |
499c09 |
+ (u8 *)&vport->fc_sparam, mbox, fc_ndlp->nlp_rpi);
|
|
Daniel Wagner |
499c09 |
+ if (rc) {
|
|
Daniel Wagner |
499c09 |
+ rc = -EACCES;
|
|
Daniel Wagner |
499c09 |
+ goto out;
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ fc_ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
|
|
Daniel Wagner |
499c09 |
+ mbox->mbox_cmpl = lpfc_mbx_cmpl_fc_reg_login;
|
|
Daniel Wagner |
499c09 |
+ mbox->ctx_ndlp = lpfc_nlp_get(fc_ndlp);
|
|
Daniel Wagner |
499c09 |
+ if (!mbox->ctx_ndlp) {
|
|
Daniel Wagner |
499c09 |
+ rc = -ENOMEM;
|
|
Daniel Wagner |
499c09 |
+ goto out_mem;
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ mbox->vport = vport;
|
|
Daniel Wagner |
499c09 |
+ rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
|
|
Daniel Wagner |
499c09 |
+ if (rc == MBX_NOT_FINISHED) {
|
|
Daniel Wagner |
499c09 |
+ rc = -ENODEV;
|
|
Daniel Wagner |
499c09 |
+ lpfc_nlp_put(fc_ndlp);
|
|
Daniel Wagner |
499c09 |
+ goto out_mem;
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
+ /* Success path. Exit. */
|
|
Daniel Wagner |
499c09 |
+ lpfc_nlp_set_state(vport, fc_ndlp,
|
|
Daniel Wagner |
499c09 |
+ NLP_STE_REG_LOGIN_ISSUE);
|
|
Daniel Wagner |
499c09 |
+ return 0;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ out_mem:
|
|
Daniel Wagner |
499c09 |
+ fc_ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
|
|
Daniel Wagner |
499c09 |
+ mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
|
|
Daniel Wagner |
499c09 |
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
Daniel Wagner |
499c09 |
+ kfree(mp);
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ out:
|
|
Daniel Wagner |
499c09 |
+ mempool_free(mbox, phba->mbox_mem_pool);
|
|
Daniel Wagner |
499c09 |
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
|
|
Daniel Wagner |
499c09 |
+ "0938 %s: failed to format reg_login "
|
|
Daniel Wagner |
499c09 |
+ "Data: x%x x%x x%x x%x\n", __func__,
|
|
Daniel Wagner |
499c09 |
+ fc_ndlp->nlp_DID, fc_ndlp->nlp_state,
|
|
Daniel Wagner |
499c09 |
+ fc_ndlp->nlp_flag, fc_ndlp->nlp_rpi);
|
|
Daniel Wagner |
499c09 |
+ return rc;
|
|
Daniel Wagner |
499c09 |
+}
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+/**
|
|
Daniel Wagner |
499c09 |
* lpfc_cmpl_els_disc_cmd - Completion callback function for Discovery ELS cmd
|
|
Daniel Wagner |
499c09 |
* @phba: pointer to lpfc hba data structure.
|
|
Daniel Wagner |
499c09 |
* @cmdiocb: pointer to lpfc command iocb data structure.
|
|
Daniel Wagner |
499c09 |
@@ -3231,10 +3320,18 @@ lpfc_issue_els_scr(struct lpfc_vport *vp
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
|
|
Daniel Wagner |
499c09 |
ndlp->nlp_DID, ELS_CMD_SCR);
|
|
Daniel Wagner |
499c09 |
-
|
|
Daniel Wagner |
499c09 |
if (!elsiocb)
|
|
Daniel Wagner |
499c09 |
return 1;
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
+ if (phba->sli_rev == LPFC_SLI_REV4) {
|
|
Daniel Wagner |
499c09 |
+ rc = lpfc_reg_fab_ctrl_node(vport, ndlp);
|
|
Daniel Wagner |
499c09 |
+ if (rc) {
|
|
Daniel Wagner |
499c09 |
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
|
|
Daniel Wagner |
499c09 |
+ "0937 %s: Failed to reg fc node, rc %d\n",
|
|
Daniel Wagner |
499c09 |
+ __func__, rc);
|
|
Daniel Wagner |
499c09 |
+ return 1;
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
*((uint32_t *) (pcmd)) = ELS_CMD_SCR;
|
|
Daniel Wagner |
499c09 |
@@ -3522,6 +3619,17 @@ lpfc_issue_els_rdf(struct lpfc_vport *vp
|
|
Daniel Wagner |
499c09 |
if (!elsiocb)
|
|
Daniel Wagner |
499c09 |
return -ENOMEM;
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
+ if (phba->sli_rev == LPFC_SLI_REV4 &&
|
|
Daniel Wagner |
499c09 |
+ !(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
|
|
Daniel Wagner |
499c09 |
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE,
|
|
Daniel Wagner |
499c09 |
+ "0939 %s: FC_NODE x%x RPI x%x flag x%x "
|
|
Daniel Wagner |
499c09 |
+ "ste x%x type x%x Not registered\n",
|
|
Daniel Wagner |
499c09 |
+ __func__, ndlp->nlp_DID, ndlp->nlp_rpi,
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_flag, ndlp->nlp_state,
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_type);
|
|
Daniel Wagner |
499c09 |
+ return -ENODEV;
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
/* Configure the payload for the supported FPIN events. */
|
|
Daniel Wagner |
499c09 |
prdf = (struct lpfc_els_rdf_req *)
|
|
Daniel Wagner |
499c09 |
(((struct lpfc_dmabuf *)elsiocb->context2)->virt);
|
|
Daniel Wagner |
499c09 |
@@ -4396,7 +4504,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *
|
|
Daniel Wagner |
499c09 |
struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
|
|
Daniel Wagner |
499c09 |
struct lpfc_vport *vport = cmdiocb->vport;
|
|
Daniel Wagner |
499c09 |
IOCB_t *irsp;
|
|
Daniel Wagner |
499c09 |
- u32 xpt_flags = 0, did_mask = 0;
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
irsp = &rspiocb->iocb;
|
|
Daniel Wagner |
499c09 |
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
|
|
Daniel Wagner |
499c09 |
@@ -4409,6 +4516,15 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *
|
|
Daniel Wagner |
499c09 |
ndlp->nlp_DID, kref_read(&ndlp->kref), ndlp->nlp_flag,
|
|
Daniel Wagner |
499c09 |
ndlp->nlp_state, ndlp->nlp_rpi);
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
+ /* This clause allows the LOGO ACC to complete and free resources
|
|
Daniel Wagner |
499c09 |
+ * for the Fabric Domain Controller. It does deliberately skip
|
|
Daniel Wagner |
499c09 |
+ * the unreg_rpi and release rpi because some fabrics send RDP
|
|
Daniel Wagner |
499c09 |
+ * requests after logging out from the initiator.
|
|
Daniel Wagner |
499c09 |
+ */
|
|
Daniel Wagner |
499c09 |
+ if (ndlp->nlp_type & NLP_FABRIC &&
|
|
Daniel Wagner |
499c09 |
+ ((ndlp->nlp_DID & WELL_KNOWN_DID_MASK) != WELL_KNOWN_DID_MASK))
|
|
Daniel Wagner |
499c09 |
+ goto out;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
|
|
Daniel Wagner |
499c09 |
/* NPort Recovery mode or node is just allocated */
|
|
Daniel Wagner |
499c09 |
if (!lpfc_nlp_not_used(ndlp)) {
|
|
Daniel Wagner |
499c09 |
@@ -4416,16 +4532,11 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *
|
|
Daniel Wagner |
499c09 |
* If this a fabric node that cleared its transport
|
|
Daniel Wagner |
499c09 |
* registration, release the rpi.
|
|
Daniel Wagner |
499c09 |
*/
|
|
Daniel Wagner |
499c09 |
- xpt_flags = SCSI_XPT_REGD | NVME_XPT_REGD;
|
|
Daniel Wagner |
499c09 |
- did_mask = ndlp->nlp_DID & Fabric_DID_MASK;
|
|
Daniel Wagner |
499c09 |
- if (did_mask == Fabric_DID_MASK &&
|
|
Daniel Wagner |
499c09 |
- !(ndlp->fc4_xpt_flags & xpt_flags)) {
|
|
Daniel Wagner |
499c09 |
- spin_lock_irq(&ndlp->lock);
|
|
Daniel Wagner |
499c09 |
- ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
|
Daniel Wagner |
499c09 |
- if (phba->sli_rev == LPFC_SLI_REV4)
|
|
Daniel Wagner |
499c09 |
- ndlp->nlp_flag |= NLP_RELEASE_RPI;
|
|
Daniel Wagner |
499c09 |
- spin_unlock_irq(&ndlp->lock);
|
|
Daniel Wagner |
499c09 |
- }
|
|
Daniel Wagner |
499c09 |
+ spin_lock_irq(&ndlp->lock);
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
|
Daniel Wagner |
499c09 |
+ if (phba->sli_rev == LPFC_SLI_REV4)
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_flag |= NLP_RELEASE_RPI;
|
|
Daniel Wagner |
499c09 |
+ spin_unlock_irq(&ndlp->lock);
|
|
Daniel Wagner |
499c09 |
lpfc_unreg_rpi(vport, ndlp);
|
|
Daniel Wagner |
499c09 |
} else {
|
|
Daniel Wagner |
499c09 |
/* Indicate the node has already released, should
|
|
Daniel Wagner |
499c09 |
@@ -4434,7 +4545,7 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *
|
|
Daniel Wagner |
499c09 |
cmdiocb->context1 = NULL;
|
|
Daniel Wagner |
499c09 |
}
|
|
Daniel Wagner |
499c09 |
}
|
|
Daniel Wagner |
499c09 |
-
|
|
Daniel Wagner |
499c09 |
+ out:
|
|
Daniel Wagner |
499c09 |
/*
|
|
Daniel Wagner |
499c09 |
* The driver received a LOGO from the rport and has ACK'd it.
|
|
Daniel Wagner |
499c09 |
* At this point, the driver is done so release the IOCB
|
|
Daniel Wagner |
499c09 |
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
|
|
Daniel Wagner |
499c09 |
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
|
Daniel Wagner |
499c09 |
@@ -79,9 +79,7 @@ static int
|
|
Daniel Wagner |
499c09 |
lpfc_valid_xpt_node(struct lpfc_nodelist *ndlp)
|
|
Daniel Wagner |
499c09 |
{
|
|
Daniel Wagner |
499c09 |
if (ndlp->nlp_fc4_type ||
|
|
Daniel Wagner |
499c09 |
- ndlp->nlp_DID == Fabric_DID ||
|
|
Daniel Wagner |
499c09 |
- ndlp->nlp_DID == NameServer_DID ||
|
|
Daniel Wagner |
499c09 |
- ndlp->nlp_DID == FDMI_DID)
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_type & NLP_FABRIC)
|
|
Daniel Wagner |
499c09 |
return 1;
|
|
Daniel Wagner |
499c09 |
return 0;
|
|
Daniel Wagner |
499c09 |
}
|
|
Daniel Wagner |
499c09 |
@@ -828,7 +826,8 @@ lpfc_cleanup_rpis(struct lpfc_vport *vpo
|
|
Daniel Wagner |
499c09 |
if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) ||
|
|
Daniel Wagner |
499c09 |
((vport->port_type == LPFC_NPIV_PORT) &&
|
|
Daniel Wagner |
499c09 |
((ndlp->nlp_DID == NameServer_DID) ||
|
|
Daniel Wagner |
499c09 |
- (ndlp->nlp_DID == FDMI_DID))))
|
|
Daniel Wagner |
499c09 |
+ (ndlp->nlp_DID == FDMI_DID) ||
|
|
Daniel Wagner |
499c09 |
+ (ndlp->nlp_DID == Fabric_Cntl_DID))))
|
|
Daniel Wagner |
499c09 |
lpfc_unreg_rpi(vport, ndlp);
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
/* Leave Fabric nodes alone on link down */
|
|
Daniel Wagner |
499c09 |
@@ -4156,6 +4155,53 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_h
|
|
Daniel Wagner |
499c09 |
return;
|
|
Daniel Wagner |
499c09 |
}
|
|
Daniel Wagner |
499c09 |
|
|
Daniel Wagner |
499c09 |
+/*
|
|
Daniel Wagner |
499c09 |
+ * This routine handles processing a Fabric Controller REG_LOGIN mailbox
|
|
Daniel Wagner |
499c09 |
+ * command upon completion. It is setup in the LPFC_MBOXQ
|
|
Daniel Wagner |
499c09 |
+ * as the completion routine when the command is handed off to the SLI layer.
|
|
Daniel Wagner |
499c09 |
+ */
|
|
Daniel Wagner |
499c09 |
+void
|
|
Daniel Wagner |
499c09 |
+lpfc_mbx_cmpl_fc_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
|
|
Daniel Wagner |
499c09 |
+{
|
|
Daniel Wagner |
499c09 |
+ struct lpfc_vport *vport = pmb->vport;
|
|
Daniel Wagner |
499c09 |
+ MAILBOX_t *mb = &pmb->u.mb;
|
|
Daniel Wagner |
499c09 |
+ struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *)(pmb->ctx_buf);
|
|
Daniel Wagner |
499c09 |
+ struct lpfc_nodelist *ndlp;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ ndlp = (struct lpfc_nodelist *)pmb->ctx_ndlp;
|
|
Daniel Wagner |
499c09 |
+ pmb->ctx_ndlp = NULL;
|
|
Daniel Wagner |
499c09 |
+ pmb->ctx_buf = NULL;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ if (mb->mbxStatus) {
|
|
Daniel Wagner |
499c09 |
+ lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
|
|
Daniel Wagner |
499c09 |
+ "0933 %s: Register FC login error: 0x%x\n",
|
|
Daniel Wagner |
499c09 |
+ __func__, mb->mbxStatus);
|
|
Daniel Wagner |
499c09 |
+ goto out;
|
|
Daniel Wagner |
499c09 |
+ }
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ if (phba->sli_rev < LPFC_SLI_REV4)
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_rpi = mb->un.varWords[0];
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE,
|
|
Daniel Wagner |
499c09 |
+ "0934 %s: Complete FC x%x RegLogin rpi x%x ste x%x\n",
|
|
Daniel Wagner |
499c09 |
+ __func__, ndlp->nlp_DID, ndlp->nlp_rpi,
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_state);
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_flag |= NLP_RPI_REGISTERED;
|
|
Daniel Wagner |
499c09 |
+ ndlp->nlp_type |= NLP_FABRIC;
|
|
Daniel Wagner |
499c09 |
+ lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ out:
|
|
Daniel Wagner |
499c09 |
+ lpfc_mbuf_free(phba, mp->virt, mp->phys);
|
|
Daniel Wagner |
499c09 |
+ kfree(mp);
|
|
Daniel Wagner |
499c09 |
+ mempool_free(pmb, phba->mbox_mem_pool);
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ /* Drop the reference count from the mbox at the end after
|
|
Daniel Wagner |
499c09 |
+ * all the current reference to the ndlp have been done.
|
|
Daniel Wagner |
499c09 |
+ */
|
|
Daniel Wagner |
499c09 |
+ lpfc_nlp_put(ndlp);
|
|
Daniel Wagner |
499c09 |
+}
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
static void
|
|
Daniel Wagner |
499c09 |
lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
|
|
Daniel Wagner |
499c09 |
{
|
|
Daniel Wagner |
499c09 |
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
|
|
Daniel Wagner |
499c09 |
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
|
|
Daniel Wagner |
499c09 |
@@ -781,6 +781,16 @@ lpfc_rcv_logo(struct lpfc_vport *vport,
|
|
Daniel Wagner |
499c09 |
lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
|
|
Daniel Wagner |
499c09 |
else
|
|
Daniel Wagner |
499c09 |
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
+ /* This clause allows the initiator to ACC the LOGO back to the
|
|
Daniel Wagner |
499c09 |
+ * Fabric Domain Controller. It does deliberately skip all other
|
|
Daniel Wagner |
499c09 |
+ * steps because some fabrics send RDP requests after logging out
|
|
Daniel Wagner |
499c09 |
+ * from the initiator.
|
|
Daniel Wagner |
499c09 |
+ */
|
|
Daniel Wagner |
499c09 |
+ if (ndlp->nlp_type & NLP_FABRIC &&
|
|
Daniel Wagner |
499c09 |
+ ((ndlp->nlp_DID & WELL_KNOWN_DID_MASK) != WELL_KNOWN_DID_MASK))
|
|
Daniel Wagner |
499c09 |
+ return 0;
|
|
Daniel Wagner |
499c09 |
+
|
|
Daniel Wagner |
499c09 |
if (ndlp->nlp_DID == Fabric_DID) {
|
|
Daniel Wagner |
499c09 |
if (vport->port_state <= LPFC_FDISC)
|
|
Daniel Wagner |
499c09 |
goto out;
|
|
Daniel Wagner |
499c09 |
@@ -1414,6 +1424,8 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_
|
|
Daniel Wagner |
499c09 |
switch (ndlp->nlp_DID) {
|
|
Daniel Wagner |
499c09 |
case NameServer_DID:
|
|
Daniel Wagner |
499c09 |
mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;
|
|
Daniel Wagner |
499c09 |
+ /* Fabric Controller Node needs these parameters. */
|
|
Daniel Wagner |
499c09 |
+ memcpy(&ndlp->fc_sparam, sp, sizeof(struct serv_parm));
|
|
Daniel Wagner |
499c09 |
break;
|
|
Daniel Wagner |
499c09 |
case FDMI_DID:
|
|
Daniel Wagner |
499c09 |
mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login;
|
|
Daniel Wagner |
499c09 |
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
|
Daniel Wagner |
499c09 |
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
|
Daniel Wagner |
499c09 |
@@ -2758,7 +2758,6 @@ lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc
|
|
Daniel Wagner |
499c09 |
} else {
|
|
Daniel Wagner |
499c09 |
__lpfc_sli_rpi_release(vport, ndlp);
|
|
Daniel Wagner |
499c09 |
}
|
|
Daniel Wagner |
499c09 |
-
|
|
Daniel Wagner |
499c09 |
lpfc_nlp_put(ndlp);
|
|
Daniel Wagner |
499c09 |
}
|
|
Daniel Wagner |
499c09 |
}
|