scsi: lpfc: Fix SCSI LUN discovery when SCSI and NVME enabled
When enabled for both SCSI and NVME support, and connected pt2pt to a SCSI only target, the driver nodelist entry for the remote port is left in PRLI_ISSUE state and no SCSI LUNs are discovered. Works fine if only configured for SCSI support. Error was due to some of the prli points still reflecting the need to send only 1 PRLI. On a lot of fabric configs, targets were NVME only, which meant the fabric-reported protocol attributes were only telling the driver one protocol or the other. Thus things worked fine. With pt2pt, the driver must send a PRLI for both protocols as there are no hints on what the target supports. Thus pt2pt targets were hitting the multiple PRLI issues. Complete the dual PRLI support. Track explicitly whether scsi (fcp) or nvme prli's have been sent. Accurately track protocol support detected on each node as reported by the fabric or probed by PRLI traffic. 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:
parent
a51e41b671
commit
9de416ac67
|
@ -471,6 +471,7 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type)
|
||||||
"Parse GID_FTrsp: did:x%x flg:x%x x%x",
|
"Parse GID_FTrsp: did:x%x flg:x%x x%x",
|
||||||
Did, ndlp->nlp_flag, vport->fc_flag);
|
Did, ndlp->nlp_flag, vport->fc_flag);
|
||||||
|
|
||||||
|
ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
|
||||||
/* By default, the driver expects to support FCP FC4 */
|
/* By default, the driver expects to support FCP FC4 */
|
||||||
if (fc4_type == FC_TYPE_FCP)
|
if (fc4_type == FC_TYPE_FCP)
|
||||||
ndlp->nlp_fc4_type |= NLP_FC4_FCP;
|
ndlp->nlp_fc4_type |= NLP_FC4_FCP;
|
||||||
|
|
|
@ -2094,6 +2094,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
|
ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
ndlp->nlp_flag &= ~NLP_PRLI_SND;
|
ndlp->nlp_flag &= ~NLP_PRLI_SND;
|
||||||
|
|
||||||
|
/* Driver supports multiple FC4 types. Counters matter. */
|
||||||
|
vport->fc_prli_sent--;
|
||||||
|
ndlp->fc4_prli_sent--;
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
|
|
||||||
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
|
||||||
|
@ -2101,9 +2105,6 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
irsp->ulpStatus, irsp->un.ulpWord[4],
|
irsp->ulpStatus, irsp->un.ulpWord[4],
|
||||||
ndlp->nlp_DID);
|
ndlp->nlp_DID);
|
||||||
|
|
||||||
/* Ddriver supports multiple FC4 types. Counters matter. */
|
|
||||||
vport->fc_prli_sent--;
|
|
||||||
|
|
||||||
/* PRLI completes to NPort <nlp_DID> */
|
/* PRLI completes to NPort <nlp_DID> */
|
||||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
|
||||||
"0103 PRLI completes to NPort x%06x "
|
"0103 PRLI completes to NPort x%06x "
|
||||||
|
@ -2117,7 +2118,6 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
|
|
||||||
if (irsp->ulpStatus) {
|
if (irsp->ulpStatus) {
|
||||||
/* Check for retry */
|
/* Check for retry */
|
||||||
ndlp->fc4_prli_sent--;
|
|
||||||
if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
|
if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
|
||||||
/* ELS command is being retried */
|
/* ELS command is being retried */
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -2196,6 +2196,15 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
ndlp->nlp_fc4_type |= NLP_FC4_NVME;
|
ndlp->nlp_fc4_type |= NLP_FC4_NVME;
|
||||||
local_nlp_type = ndlp->nlp_fc4_type;
|
local_nlp_type = ndlp->nlp_fc4_type;
|
||||||
|
|
||||||
|
/* This routine will issue 1 or 2 PRLIs, so zero all the ndlp
|
||||||
|
* fields here before any of them can complete.
|
||||||
|
*/
|
||||||
|
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||||
|
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||||
|
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||||
|
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
||||||
|
ndlp->nvme_fb_size = 0;
|
||||||
|
|
||||||
send_next_prli:
|
send_next_prli:
|
||||||
if (local_nlp_type & NLP_FC4_FCP) {
|
if (local_nlp_type & NLP_FC4_FCP) {
|
||||||
/* Payload is 4 + 16 = 20 x14 bytes. */
|
/* Payload is 4 + 16 = 20 x14 bytes. */
|
||||||
|
@ -2304,6 +2313,13 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
|
elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
ndlp->nlp_flag |= NLP_PRLI_SND;
|
ndlp->nlp_flag |= NLP_PRLI_SND;
|
||||||
|
|
||||||
|
/* The vport counters are used for lpfc_scan_finished, but
|
||||||
|
* the ndlp is used to track outstanding PRLIs for different
|
||||||
|
* FC4 types.
|
||||||
|
*/
|
||||||
|
vport->fc_prli_sent++;
|
||||||
|
ndlp->fc4_prli_sent++;
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
|
if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
|
||||||
IOCB_ERROR) {
|
IOCB_ERROR) {
|
||||||
|
@ -2314,12 +2330,6 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The vport counters are used for lpfc_scan_finished, but
|
|
||||||
* the ndlp is used to track outstanding PRLIs for different
|
|
||||||
* FC4 types.
|
|
||||||
*/
|
|
||||||
vport->fc_prli_sent++;
|
|
||||||
ndlp->fc4_prli_sent++;
|
|
||||||
|
|
||||||
/* The driver supports 2 FC4 types. Make sure
|
/* The driver supports 2 FC4 types. Make sure
|
||||||
* a PRLI is issued for all types before exiting.
|
* a PRLI is issued for all types before exiting.
|
||||||
|
|
|
@ -390,6 +390,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
||||||
|
ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
|
||||||
|
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
||||||
|
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
||||||
|
|
||||||
/* Check for Nport to NPort pt2pt protocol */
|
/* Check for Nport to NPort pt2pt protocol */
|
||||||
if ((vport->fc_flag & FC_PT2PT) &&
|
if ((vport->fc_flag & FC_PT2PT) &&
|
||||||
!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
!(vport->fc_flag & FC_PT2PT_PLOGI)) {
|
||||||
|
@ -777,9 +782,6 @@ lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
lp = (uint32_t *) pcmd->virt;
|
lp = (uint32_t *) pcmd->virt;
|
||||||
npr = (PRLI *) ((uint8_t *) lp + sizeof (uint32_t));
|
npr = (PRLI *) ((uint8_t *) lp + sizeof (uint32_t));
|
||||||
|
|
||||||
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
|
||||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
|
||||||
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
|
||||||
if ((npr->prliType == PRLI_FCP_TYPE) ||
|
if ((npr->prliType == PRLI_FCP_TYPE) ||
|
||||||
(npr->prliType == PRLI_NVME_TYPE)) {
|
(npr->prliType == PRLI_NVME_TYPE)) {
|
||||||
if (npr->initiatorFunc) {
|
if (npr->initiatorFunc) {
|
||||||
|
@ -804,8 +806,12 @@ lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
* type. Target mode does not issue gft_id so doesn't get
|
* type. Target mode does not issue gft_id so doesn't get
|
||||||
* the fc4 type set until now.
|
* the fc4 type set until now.
|
||||||
*/
|
*/
|
||||||
if ((phba->nvmet_support) && (npr->prliType == PRLI_NVME_TYPE))
|
if (phba->nvmet_support && (npr->prliType == PRLI_NVME_TYPE)) {
|
||||||
ndlp->nlp_fc4_type |= NLP_FC4_NVME;
|
ndlp->nlp_fc4_type |= NLP_FC4_NVME;
|
||||||
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||||
|
}
|
||||||
|
if (npr->prliType == PRLI_FCP_TYPE)
|
||||||
|
ndlp->nlp_fc4_type |= NLP_FC4_FCP;
|
||||||
}
|
}
|
||||||
if (rport) {
|
if (rport) {
|
||||||
/* We need to update the rport role values */
|
/* We need to update the rport role values */
|
||||||
|
@ -1591,7 +1597,6 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
|
||||||
if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
|
if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
|
||||||
lpfc_rcv_prli(vport, ndlp, cmdiocb);
|
lpfc_rcv_prli(vport, ndlp, cmdiocb);
|
||||||
lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
|
lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
|
||||||
} else {
|
} else {
|
||||||
/* RPI registration has not completed. Reject the PRLI
|
/* RPI registration has not completed. Reject the PRLI
|
||||||
* to prevent an illegal state transition when the
|
* to prevent an illegal state transition when the
|
||||||
|
@ -1602,6 +1607,7 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
|
||||||
stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
|
stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
|
||||||
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
|
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
|
||||||
ndlp, NULL);
|
ndlp, NULL);
|
||||||
|
return ndlp->nlp_state;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* Initiator mode. */
|
/* Initiator mode. */
|
||||||
|
@ -1957,13 +1963,6 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
return ndlp->nlp_state;
|
return ndlp->nlp_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check out PRLI rsp */
|
|
||||||
ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
|
|
||||||
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
|
|
||||||
|
|
||||||
/* NVME or FCP first burst must be negotiated for each PRLI. */
|
|
||||||
ndlp->nlp_flag &= ~NLP_FIRSTBURST;
|
|
||||||
ndlp->nvme_fb_size = 0;
|
|
||||||
if (npr && (npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
|
if (npr && (npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
|
||||||
(npr->prliType == PRLI_FCP_TYPE)) {
|
(npr->prliType == PRLI_FCP_TYPE)) {
|
||||||
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
|
lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
|
||||||
|
@ -1980,8 +1979,6 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
if (npr->Retry)
|
if (npr->Retry)
|
||||||
ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
|
ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
|
||||||
|
|
||||||
/* PRLI completed. Decrement count. */
|
|
||||||
ndlp->fc4_prli_sent--;
|
|
||||||
} else if (nvpr &&
|
} else if (nvpr &&
|
||||||
(bf_get_be32(prli_acc_rsp_code, nvpr) ==
|
(bf_get_be32(prli_acc_rsp_code, nvpr) ==
|
||||||
PRLI_REQ_EXECUTED) &&
|
PRLI_REQ_EXECUTED) &&
|
||||||
|
@ -2026,8 +2023,6 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
be32_to_cpu(nvpr->word5),
|
be32_to_cpu(nvpr->word5),
|
||||||
ndlp->nlp_flag, ndlp->nlp_fcp_info,
|
ndlp->nlp_flag, ndlp->nlp_fcp_info,
|
||||||
ndlp->nlp_type);
|
ndlp->nlp_type);
|
||||||
/* PRLI completed. Decrement count. */
|
|
||||||
ndlp->fc4_prli_sent--;
|
|
||||||
}
|
}
|
||||||
if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
|
if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
|
||||||
(vport->port_type == LPFC_NPIV_PORT) &&
|
(vport->port_type == LPFC_NPIV_PORT) &&
|
||||||
|
@ -2051,7 +2046,8 @@ out_err:
|
||||||
ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
|
ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
|
||||||
if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET))
|
if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET))
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
|
||||||
else
|
else if (ndlp->nlp_type &
|
||||||
|
(NLP_FCP_INITIATOR | NLP_NVME_INITIATOR))
|
||||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||||
} else
|
} else
|
||||||
lpfc_printf_vlog(vport,
|
lpfc_printf_vlog(vport,
|
||||||
|
|
Loading…
Reference in New Issue