diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 91 |
1 files changed, 82 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index a81d43306d17..d807f36ba4f9 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -771,6 +771,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
771 | struct lpfc_nodelist *ndlp = cmdiocb->context1; | 771 | struct lpfc_nodelist *ndlp = cmdiocb->context1; |
772 | struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; | 772 | struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; |
773 | struct serv_parm *sp; | 773 | struct serv_parm *sp; |
774 | uint16_t fcf_index; | ||
774 | int rc; | 775 | int rc; |
775 | 776 | ||
776 | /* Check to see if link went down during discovery */ | 777 | /* Check to see if link went down during discovery */ |
@@ -788,6 +789,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
788 | vport->port_state); | 789 | vport->port_state); |
789 | 790 | ||
790 | if (irsp->ulpStatus) { | 791 | if (irsp->ulpStatus) { |
792 | /* | ||
793 | * In case of FIP mode, perform round robin FCF failover | ||
794 | * due to new FCF discovery | ||
795 | */ | ||
796 | if ((phba->hba_flag & HBA_FIP_SUPPORT) && | ||
797 | (phba->fcf.fcf_flag & FCF_DISCOVERY)) { | ||
798 | lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS, | ||
799 | "2611 FLOGI failed on registered " | ||
800 | "FCF record fcf_index:%d, trying " | ||
801 | "to perform round robin failover\n", | ||
802 | phba->fcf.current_rec.fcf_indx); | ||
803 | fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba); | ||
804 | if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) { | ||
805 | /* | ||
806 | * Exhausted the eligible FCF record list, | ||
807 | * fail through to retry FLOGI on current | ||
808 | * FCF record. | ||
809 | */ | ||
810 | lpfc_printf_log(phba, KERN_WARNING, | ||
811 | LOG_FIP | LOG_ELS, | ||
812 | "2760 FLOGI exhausted FCF " | ||
813 | "round robin failover list, " | ||
814 | "retry FLOGI on the current " | ||
815 | "registered FCF index:%d\n", | ||
816 | phba->fcf.current_rec.fcf_indx); | ||
817 | spin_lock_irq(&phba->hbalock); | ||
818 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
819 | spin_unlock_irq(&phba->hbalock); | ||
820 | } else { | ||
821 | rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba, | ||
822 | fcf_index); | ||
823 | if (rc) { | ||
824 | lpfc_printf_log(phba, KERN_WARNING, | ||
825 | LOG_FIP | LOG_ELS, | ||
826 | "2761 FLOGI round " | ||
827 | "robin FCF failover " | ||
828 | "read FCF failed " | ||
829 | "rc:x%x, fcf_index:" | ||
830 | "%d\n", rc, | ||
831 | phba->fcf.current_rec.fcf_indx); | ||
832 | spin_lock_irq(&phba->hbalock); | ||
833 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
834 | spin_unlock_irq(&phba->hbalock); | ||
835 | } else | ||
836 | goto out; | ||
837 | } | ||
838 | } | ||
839 | |||
791 | /* Check for retry */ | 840 | /* Check for retry */ |
792 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) | 841 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) |
793 | goto out; | 842 | goto out; |
@@ -841,8 +890,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
841 | else | 890 | else |
842 | rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); | 891 | rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); |
843 | 892 | ||
844 | if (!rc) | 893 | if (!rc) { |
894 | /* Mark the FCF discovery process done */ | ||
895 | lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS, | ||
896 | "2769 FLOGI successful on FCF record: " | ||
897 | "current_fcf_index:x%x, terminate FCF " | ||
898 | "round robin failover process\n", | ||
899 | phba->fcf.current_rec.fcf_indx); | ||
900 | spin_lock_irq(&phba->hbalock); | ||
901 | phba->fcf.fcf_flag &= ~FCF_DISCOVERY; | ||
902 | spin_unlock_irq(&phba->hbalock); | ||
845 | goto out; | 903 | goto out; |
904 | } | ||
846 | } | 905 | } |
847 | 906 | ||
848 | flogifail: | 907 | flogifail: |
@@ -6075,21 +6134,18 @@ mbox_err_exit: | |||
6075 | } | 6134 | } |
6076 | 6135 | ||
6077 | /** | 6136 | /** |
6078 | * lpfc_retry_pport_discovery - Start timer to retry FLOGI. | 6137 | * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer |
6079 | * @phba: pointer to lpfc hba data structure. | 6138 | * @phba: pointer to lpfc hba data structure. |
6080 | * | 6139 | * |
6081 | * This routine abort all pending discovery commands and | 6140 | * This routine cancels the retry delay timers to all the vports. |
6082 | * start a timer to retry FLOGI for the physical port | ||
6083 | * discovery. | ||
6084 | **/ | 6141 | **/ |
6085 | void | 6142 | void |
6086 | lpfc_retry_pport_discovery(struct lpfc_hba *phba) | 6143 | lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba) |
6087 | { | 6144 | { |
6088 | struct lpfc_vport **vports; | 6145 | struct lpfc_vport **vports; |
6089 | struct lpfc_nodelist *ndlp; | 6146 | struct lpfc_nodelist *ndlp; |
6090 | struct Scsi_Host *shost; | ||
6091 | int i; | ||
6092 | uint32_t link_state; | 6147 | uint32_t link_state; |
6148 | int i; | ||
6093 | 6149 | ||
6094 | /* Treat this failure as linkdown for all vports */ | 6150 | /* Treat this failure as linkdown for all vports */ |
6095 | link_state = phba->link_state; | 6151 | link_state = phba->link_state; |
@@ -6107,13 +6163,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba) | |||
6107 | } | 6163 | } |
6108 | lpfc_destroy_vport_work_array(phba, vports); | 6164 | lpfc_destroy_vport_work_array(phba, vports); |
6109 | } | 6165 | } |
6166 | } | ||
6167 | |||
6168 | /** | ||
6169 | * lpfc_retry_pport_discovery - Start timer to retry FLOGI. | ||
6170 | * @phba: pointer to lpfc hba data structure. | ||
6171 | * | ||
6172 | * This routine abort all pending discovery commands and | ||
6173 | * start a timer to retry FLOGI for the physical port | ||
6174 | * discovery. | ||
6175 | **/ | ||
6176 | void | ||
6177 | lpfc_retry_pport_discovery(struct lpfc_hba *phba) | ||
6178 | { | ||
6179 | struct lpfc_nodelist *ndlp; | ||
6180 | struct Scsi_Host *shost; | ||
6181 | |||
6182 | /* Cancel the all vports retry delay retry timers */ | ||
6183 | lpfc_cancel_all_vport_retry_delay_timer(phba); | ||
6110 | 6184 | ||
6111 | /* If fabric require FLOGI, then re-instantiate physical login */ | 6185 | /* If fabric require FLOGI, then re-instantiate physical login */ |
6112 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 6186 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
6113 | if (!ndlp) | 6187 | if (!ndlp) |
6114 | return; | 6188 | return; |
6115 | 6189 | ||
6116 | |||
6117 | shost = lpfc_shost_from_vport(phba->pport); | 6190 | shost = lpfc_shost_from_vport(phba->pport); |
6118 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 6191 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
6119 | spin_lock_irq(shost->host_lock); | 6192 | spin_lock_irq(shost->host_lock); |