aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c145
1 files changed, 132 insertions, 13 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 2cc39684ce97..08b6634cb994 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -50,9 +50,6 @@ static int lpfc_issue_els_fdisc(struct lpfc_vport *vport,
50 struct lpfc_nodelist *ndlp, uint8_t retry); 50 struct lpfc_nodelist *ndlp, uint8_t retry);
51static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba, 51static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba,
52 struct lpfc_iocbq *iocb); 52 struct lpfc_iocbq *iocb);
53static void lpfc_register_new_vport(struct lpfc_hba *phba,
54 struct lpfc_vport *vport,
55 struct lpfc_nodelist *ndlp);
56 53
57static int lpfc_max_els_tries = 3; 54static int lpfc_max_els_tries = 3;
58 55
@@ -592,6 +589,15 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
592 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 589 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
593 spin_unlock_irq(shost->host_lock); 590 spin_unlock_irq(shost->host_lock);
594 } 591 }
592 /*
593 * If VPI is unreged, driver need to do INIT_VPI
594 * before re-registering
595 */
596 if (phba->sli_rev == LPFC_SLI_REV4) {
597 spin_lock_irq(shost->host_lock);
598 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
599 spin_unlock_irq(shost->host_lock);
600 }
595 } 601 }
596 602
597 if (phba->sli_rev < LPFC_SLI_REV4) { 603 if (phba->sli_rev < LPFC_SLI_REV4) {
@@ -604,10 +610,13 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
604 } else { 610 } else {
605 ndlp->nlp_type |= NLP_FABRIC; 611 ndlp->nlp_type |= NLP_FABRIC;
606 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 612 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
607 if (vport->vpi_state & LPFC_VPI_REGISTERED) { 613 if ((!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) &&
614 (vport->vpi_state & LPFC_VPI_REGISTERED)) {
608 lpfc_start_fdiscs(phba); 615 lpfc_start_fdiscs(phba);
609 lpfc_do_scr_ns_plogi(phba, vport); 616 lpfc_do_scr_ns_plogi(phba, vport);
610 } else 617 } else if (vport->fc_flag & FC_VFI_REGISTERED)
618 lpfc_issue_init_vpi(vport);
619 else
611 lpfc_issue_reg_vfi(vport); 620 lpfc_issue_reg_vfi(vport);
612 } 621 }
613 return 0; 622 return 0;
@@ -804,6 +813,9 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
804 irsp->ulpTimeout); 813 irsp->ulpTimeout);
805 goto flogifail; 814 goto flogifail;
806 } 815 }
816 spin_lock_irq(shost->host_lock);
817 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
818 spin_unlock_irq(shost->host_lock);
807 819
808 /* 820 /*
809 * The FLogI succeeded. Sync the data for the CPU before 821 * The FLogI succeeded. Sync the data for the CPU before
@@ -2720,7 +2732,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2720 if (did == FDMI_DID) 2732 if (did == FDMI_DID)
2721 retry = 1; 2733 retry = 1;
2722 2734
2723 if ((cmd == ELS_CMD_FLOGI) && 2735 if (((cmd == ELS_CMD_FLOGI) || (cmd == ELS_CMD_FDISC)) &&
2724 (phba->fc_topology != TOPOLOGY_LOOP) && 2736 (phba->fc_topology != TOPOLOGY_LOOP) &&
2725 !lpfc_error_lost_link(irsp)) { 2737 !lpfc_error_lost_link(irsp)) {
2726 /* FLOGI retry policy */ 2738 /* FLOGI retry policy */
@@ -4385,7 +4397,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4385 4397
4386 did = Fabric_DID; 4398 did = Fabric_DID;
4387 4399
4388 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) { 4400 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
4389 /* For a FLOGI we accept, then if our portname is greater 4401 /* For a FLOGI we accept, then if our portname is greater
4390 * then the remote portname we initiate Nport login. 4402 * then the remote portname we initiate Nport login.
4391 */ 4403 */
@@ -5915,6 +5927,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5915 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 5927 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5916 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; 5928 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
5917 MAILBOX_t *mb = &pmb->u.mb; 5929 MAILBOX_t *mb = &pmb->u.mb;
5930 int rc;
5918 5931
5919 spin_lock_irq(shost->host_lock); 5932 spin_lock_irq(shost->host_lock);
5920 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; 5933 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
@@ -5936,6 +5949,26 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5936 spin_unlock_irq(shost->host_lock); 5949 spin_unlock_irq(shost->host_lock);
5937 lpfc_can_disctmo(vport); 5950 lpfc_can_disctmo(vport);
5938 break; 5951 break;
5952 /* If reg_vpi fail with invalid VPI status, re-init VPI */
5953 case 0x20:
5954 spin_lock_irq(shost->host_lock);
5955 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
5956 spin_unlock_irq(shost->host_lock);
5957 lpfc_init_vpi(phba, pmb, vport->vpi);
5958 pmb->vport = vport;
5959 pmb->mbox_cmpl = lpfc_init_vpi_cmpl;
5960 rc = lpfc_sli_issue_mbox(phba, pmb,
5961 MBX_NOWAIT);
5962 if (rc == MBX_NOT_FINISHED) {
5963 lpfc_printf_vlog(vport,
5964 KERN_ERR, LOG_MBOX,
5965 "2732 Failed to issue INIT_VPI"
5966 " mailbox command\n");
5967 } else {
5968 lpfc_nlp_put(ndlp);
5969 return;
5970 }
5971
5939 default: 5972 default:
5940 /* Try to recover from this error */ 5973 /* Try to recover from this error */
5941 lpfc_mbx_unreg_vpi(vport); 5974 lpfc_mbx_unreg_vpi(vport);
@@ -5949,13 +5982,17 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5949 break; 5982 break;
5950 } 5983 }
5951 } else { 5984 } else {
5985 spin_lock_irq(shost->host_lock);
5952 vport->vpi_state |= LPFC_VPI_REGISTERED; 5986 vport->vpi_state |= LPFC_VPI_REGISTERED;
5953 if (vport == phba->pport) 5987 spin_unlock_irq(shost->host_lock);
5988 if (vport == phba->pport) {
5954 if (phba->sli_rev < LPFC_SLI_REV4) 5989 if (phba->sli_rev < LPFC_SLI_REV4)
5955 lpfc_issue_fabric_reglogin(vport); 5990 lpfc_issue_fabric_reglogin(vport);
5956 else 5991 else {
5957 lpfc_issue_reg_vfi(vport); 5992 lpfc_start_fdiscs(phba);
5958 else 5993 lpfc_do_scr_ns_plogi(phba, vport);
5994 }
5995 } else
5959 lpfc_do_scr_ns_plogi(phba, vport); 5996 lpfc_do_scr_ns_plogi(phba, vport);
5960 } 5997 }
5961 5998
@@ -5977,7 +6014,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5977 * This routine registers the @vport as a new virtual port with a HBA. 6014 * This routine registers the @vport as a new virtual port with a HBA.
5978 * It is done through a registering vpi mailbox command. 6015 * It is done through a registering vpi mailbox command.
5979 **/ 6016 **/
5980static void 6017void
5981lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, 6018lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
5982 struct lpfc_nodelist *ndlp) 6019 struct lpfc_nodelist *ndlp)
5983{ 6020{
@@ -6018,6 +6055,78 @@ mbox_err_exit:
6018} 6055}
6019 6056
6020/** 6057/**
6058 * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
6059 * @phba: pointer to lpfc hba data structure.
6060 *
6061 * This routine abort all pending discovery commands and
6062 * start a timer to retry FLOGI for the physical port
6063 * discovery.
6064 **/
6065void
6066lpfc_retry_pport_discovery(struct lpfc_hba *phba)
6067{
6068 struct lpfc_vport **vports;
6069 struct lpfc_nodelist *ndlp;
6070 struct Scsi_Host *shost;
6071 int i;
6072 uint32_t link_state;
6073
6074 /* Treat this failure as linkdown for all vports */
6075 link_state = phba->link_state;
6076 lpfc_linkdown(phba);
6077 phba->link_state = link_state;
6078
6079 vports = lpfc_create_vport_work_array(phba);
6080
6081 if (vports) {
6082 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
6083 ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
6084 if (ndlp)
6085 lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
6086 lpfc_els_flush_cmd(vports[i]);
6087 }
6088 lpfc_destroy_vport_work_array(phba, vports);
6089 }
6090
6091 /* If fabric require FLOGI, then re-instantiate physical login */
6092 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
6093 if (!ndlp)
6094 return;
6095
6096
6097 shost = lpfc_shost_from_vport(phba->pport);
6098 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
6099 spin_lock_irq(shost->host_lock);
6100 ndlp->nlp_flag |= NLP_DELAY_TMO;
6101 spin_unlock_irq(shost->host_lock);
6102 ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
6103 phba->pport->port_state = LPFC_FLOGI;
6104 return;
6105}
6106
6107/**
6108 * lpfc_fabric_login_reqd - Check if FLOGI required.
6109 * @phba: pointer to lpfc hba data structure.
6110 * @cmdiocb: pointer to FDISC command iocb.
6111 * @rspiocb: pointer to FDISC response iocb.
6112 *
6113 * This routine checks if a FLOGI is reguired for FDISC
6114 * to succeed.
6115 **/
6116static int
6117lpfc_fabric_login_reqd(struct lpfc_hba *phba,
6118 struct lpfc_iocbq *cmdiocb,
6119 struct lpfc_iocbq *rspiocb)
6120{
6121
6122 if ((rspiocb->iocb.ulpStatus != IOSTAT_FABRIC_RJT) ||
6123 (rspiocb->iocb.un.ulpWord[4] != RJT_LOGIN_REQUIRED))
6124 return 0;
6125 else
6126 return 1;
6127}
6128
6129/**
6021 * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command 6130 * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command
6022 * @phba: pointer to lpfc hba data structure. 6131 * @phba: pointer to lpfc hba data structure.
6023 * @cmdiocb: pointer to lpfc command iocb data structure. 6132 * @cmdiocb: pointer to lpfc command iocb data structure.
@@ -6066,6 +6175,12 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6066 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID); 6175 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
6067 6176
6068 if (irsp->ulpStatus) { 6177 if (irsp->ulpStatus) {
6178
6179 if (lpfc_fabric_login_reqd(phba, cmdiocb, rspiocb)) {
6180 lpfc_retry_pport_discovery(phba);
6181 goto out;
6182 }
6183
6069 /* Check for retry */ 6184 /* Check for retry */
6070 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) 6185 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
6071 goto out; 6186 goto out;
@@ -6076,6 +6191,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6076 goto fdisc_failed; 6191 goto fdisc_failed;
6077 } 6192 }
6078 spin_lock_irq(shost->host_lock); 6193 spin_lock_irq(shost->host_lock);
6194 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
6079 vport->fc_flag |= FC_FABRIC; 6195 vport->fc_flag |= FC_FABRIC;
6080 if (vport->phba->fc_topology == TOPOLOGY_LOOP) 6196 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
6081 vport->fc_flag |= FC_PUBLIC_LOOP; 6197 vport->fc_flag |= FC_PUBLIC_LOOP;
@@ -6103,10 +6219,13 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6103 lpfc_mbx_unreg_vpi(vport); 6219 lpfc_mbx_unreg_vpi(vport);
6104 spin_lock_irq(shost->host_lock); 6220 spin_lock_irq(shost->host_lock);
6105 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6221 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
6222 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
6106 spin_unlock_irq(shost->host_lock); 6223 spin_unlock_irq(shost->host_lock);
6107 } 6224 }
6108 6225
6109 if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) 6226 if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)
6227 lpfc_issue_init_vpi(vport);
6228 else if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
6110 lpfc_register_new_vport(phba, vport, ndlp); 6229 lpfc_register_new_vport(phba, vport, ndlp);
6111 else 6230 else
6112 lpfc_do_scr_ns_plogi(phba, vport); 6231 lpfc_do_scr_ns_plogi(phba, vport);