diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-18 19:54:31 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-18 19:54:31 -0400 |
commit | 961cde93dee2658000ead32abffb8ddf0727abe0 (patch) | |
tree | 2419e204132abe2ec2bb7f08bd20042573cc9bd6 /drivers/scsi/lpfc/lpfc_els.c | |
parent | f82c37e7bb4c4d9b6a476c642d5c2d2efbd6f240 (diff) | |
parent | 0d9dc7c8b9b7fa0f53647423b41056ee1beed735 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (69 commits)
[SCSI] scsi_transport_fc: Fix synchronization issue while deleting vport
[SCSI] bfa: Update the driver version to 2.1.2.1.
[SCSI] bfa: Remove unused header files and did some cleanup.
[SCSI] bfa: Handle SCSI IO underrun case.
[SCSI] bfa: FCS and include file changes.
[SCSI] bfa: Modified the portstats get/clear logic
[SCSI] bfa: Replace bfa_get_attr() with specific APIs
[SCSI] bfa: New portlog entries for events (FIP/FLOGI/FDISC/LOGO).
[SCSI] bfa: Rename pport to fcport in BFA FCS.
[SCSI] bfa: IOC fixes, check for IOC down condition.
[SCSI] bfa: In MSIX mode, ignore spurious RME interrupts when FCoE ports are in FW mismatch state.
[SCSI] bfa: Fix Command Queue (CPE) full condition check and ack CPE interrupt.
[SCSI] bfa: IOC recovery fix in fcmode.
[SCSI] bfa: AEN and byte alignment fixes.
[SCSI] bfa: Introduce a link notification state machine.
[SCSI] bfa: Added firmware save clear feature for BFA driver.
[SCSI] bfa: FCS authentication related changes.
[SCSI] bfa: PCI VPD, FIP and include file changes.
[SCSI] bfa: Fix to copy fpma MAC when requested by user space application.
[SCSI] bfa: RPORT state machine: direct attach mode fix.
...
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 142 |
1 files changed, 121 insertions, 21 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 2a40a6eabf4d..ee980bd66869 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; |
@@ -806,9 +855,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
806 | } | 855 | } |
807 | 856 | ||
808 | /* FLOGI failure */ | 857 | /* FLOGI failure */ |
809 | lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, | 858 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
810 | "0100 FLOGI failure Data: x%x x%x " | 859 | "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n", |
811 | "x%x\n", | ||
812 | irsp->ulpStatus, irsp->un.ulpWord[4], | 860 | irsp->ulpStatus, irsp->un.ulpWord[4], |
813 | irsp->ulpTimeout); | 861 | irsp->ulpTimeout); |
814 | goto flogifail; | 862 | goto flogifail; |
@@ -842,8 +890,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
842 | else | 890 | else |
843 | rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); | 891 | rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); |
844 | 892 | ||
845 | 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); | ||
846 | goto out; | 903 | goto out; |
904 | } | ||
847 | } | 905 | } |
848 | 906 | ||
849 | flogifail: | 907 | flogifail: |
@@ -1409,6 +1467,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1409 | goto out; | 1467 | goto out; |
1410 | } | 1468 | } |
1411 | /* PLOGI failed */ | 1469 | /* PLOGI failed */ |
1470 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
1471 | "2753 PLOGI failure DID:%06X Status:x%x/x%x\n", | ||
1472 | ndlp->nlp_DID, irsp->ulpStatus, | ||
1473 | irsp->un.ulpWord[4]); | ||
1412 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1474 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1413 | if (lpfc_error_lost_link(irsp)) | 1475 | if (lpfc_error_lost_link(irsp)) |
1414 | rc = NLP_STE_FREED_NODE; | 1476 | rc = NLP_STE_FREED_NODE; |
@@ -1577,6 +1639,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1577 | goto out; | 1639 | goto out; |
1578 | } | 1640 | } |
1579 | /* PRLI failed */ | 1641 | /* PRLI failed */ |
1642 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
1643 | "2754 PRLI failure DID:%06X Status:x%x/x%x\n", | ||
1644 | ndlp->nlp_DID, irsp->ulpStatus, | ||
1645 | irsp->un.ulpWord[4]); | ||
1580 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1646 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1581 | if (lpfc_error_lost_link(irsp)) | 1647 | if (lpfc_error_lost_link(irsp)) |
1582 | goto out; | 1648 | goto out; |
@@ -1860,6 +1926,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1860 | goto out; | 1926 | goto out; |
1861 | } | 1927 | } |
1862 | /* ADISC failed */ | 1928 | /* ADISC failed */ |
1929 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
1930 | "2755 ADISC failure DID:%06X Status:x%x/x%x\n", | ||
1931 | ndlp->nlp_DID, irsp->ulpStatus, | ||
1932 | irsp->un.ulpWord[4]); | ||
1863 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1933 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1864 | if (!lpfc_error_lost_link(irsp)) | 1934 | if (!lpfc_error_lost_link(irsp)) |
1865 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1935 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
@@ -2009,6 +2079,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2009 | /* ELS command is being retried */ | 2079 | /* ELS command is being retried */ |
2010 | goto out; | 2080 | goto out; |
2011 | /* LOGO failed */ | 2081 | /* LOGO failed */ |
2082 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | ||
2083 | "2756 LOGO failure DID:%06X Status:x%x/x%x\n", | ||
2084 | ndlp->nlp_DID, irsp->ulpStatus, | ||
2085 | irsp->un.ulpWord[4]); | ||
2012 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 2086 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
2013 | if (lpfc_error_lost_link(irsp)) | 2087 | if (lpfc_error_lost_link(irsp)) |
2014 | goto out; | 2088 | goto out; |
@@ -5989,7 +6063,12 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
5989 | if (phba->sli_rev < LPFC_SLI_REV4) | 6063 | if (phba->sli_rev < LPFC_SLI_REV4) |
5990 | lpfc_issue_fabric_reglogin(vport); | 6064 | lpfc_issue_fabric_reglogin(vport); |
5991 | else { | 6065 | else { |
5992 | lpfc_start_fdiscs(phba); | 6066 | /* |
6067 | * If the physical port is instantiated using | ||
6068 | * FDISC, do not start vport discovery. | ||
6069 | */ | ||
6070 | if (vport->port_state != LPFC_FDISC) | ||
6071 | lpfc_start_fdiscs(phba); | ||
5993 | lpfc_do_scr_ns_plogi(phba, vport); | 6072 | lpfc_do_scr_ns_plogi(phba, vport); |
5994 | } | 6073 | } |
5995 | } else | 6074 | } else |
@@ -6055,21 +6134,18 @@ mbox_err_exit: | |||
6055 | } | 6134 | } |
6056 | 6135 | ||
6057 | /** | 6136 | /** |
6058 | * lpfc_retry_pport_discovery - Start timer to retry FLOGI. | 6137 | * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer |
6059 | * @phba: pointer to lpfc hba data structure. | 6138 | * @phba: pointer to lpfc hba data structure. |
6060 | * | 6139 | * |
6061 | * This routine abort all pending discovery commands and | 6140 | * This routine cancels the retry delay timers to all the vports. |
6062 | * start a timer to retry FLOGI for the physical port | ||
6063 | * discovery. | ||
6064 | **/ | 6141 | **/ |
6065 | void | 6142 | void |
6066 | lpfc_retry_pport_discovery(struct lpfc_hba *phba) | 6143 | lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba) |
6067 | { | 6144 | { |
6068 | struct lpfc_vport **vports; | 6145 | struct lpfc_vport **vports; |
6069 | struct lpfc_nodelist *ndlp; | 6146 | struct lpfc_nodelist *ndlp; |
6070 | struct Scsi_Host *shost; | ||
6071 | int i; | ||
6072 | uint32_t link_state; | 6147 | uint32_t link_state; |
6148 | int i; | ||
6073 | 6149 | ||
6074 | /* Treat this failure as linkdown for all vports */ | 6150 | /* Treat this failure as linkdown for all vports */ |
6075 | link_state = phba->link_state; | 6151 | link_state = phba->link_state; |
@@ -6087,13 +6163,30 @@ lpfc_retry_pport_discovery(struct lpfc_hba *phba) | |||
6087 | } | 6163 | } |
6088 | lpfc_destroy_vport_work_array(phba, vports); | 6164 | lpfc_destroy_vport_work_array(phba, vports); |
6089 | } | 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); | ||
6090 | 6184 | ||
6091 | /* If fabric require FLOGI, then re-instantiate physical login */ | 6185 | /* If fabric require FLOGI, then re-instantiate physical login */ |
6092 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); | 6186 | ndlp = lpfc_findnode_did(phba->pport, Fabric_DID); |
6093 | if (!ndlp) | 6187 | if (!ndlp) |
6094 | return; | 6188 | return; |
6095 | 6189 | ||
6096 | |||
6097 | shost = lpfc_shost_from_vport(phba->pport); | 6190 | shost = lpfc_shost_from_vport(phba->pport); |
6098 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 6191 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
6099 | spin_lock_irq(shost->host_lock); | 6192 | spin_lock_irq(shost->host_lock); |
@@ -6219,7 +6312,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
6219 | lpfc_mbx_unreg_vpi(vport); | 6312 | lpfc_mbx_unreg_vpi(vport); |
6220 | spin_lock_irq(shost->host_lock); | 6313 | spin_lock_irq(shost->host_lock); |
6221 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; | 6314 | vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; |
6222 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | 6315 | if (phba->sli_rev == LPFC_SLI_REV4) |
6316 | vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; | ||
6223 | spin_unlock_irq(shost->host_lock); | 6317 | spin_unlock_irq(shost->host_lock); |
6224 | } | 6318 | } |
6225 | 6319 | ||
@@ -6797,21 +6891,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, | |||
6797 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; | 6891 | struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; |
6798 | unsigned long iflag = 0; | 6892 | unsigned long iflag = 0; |
6799 | 6893 | ||
6800 | spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); | 6894 | spin_lock_irqsave(&phba->hbalock, iflag); |
6895 | spin_lock(&phba->sli4_hba.abts_sgl_list_lock); | ||
6801 | list_for_each_entry_safe(sglq_entry, sglq_next, | 6896 | list_for_each_entry_safe(sglq_entry, sglq_next, |
6802 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { | 6897 | &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { |
6803 | if (sglq_entry->sli4_xritag == xri) { | 6898 | if (sglq_entry->sli4_xritag == xri) { |
6804 | list_del(&sglq_entry->list); | 6899 | list_del(&sglq_entry->list); |
6805 | spin_unlock_irqrestore( | ||
6806 | &phba->sli4_hba.abts_sgl_list_lock, | ||
6807 | iflag); | ||
6808 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
6809 | |||
6810 | list_add_tail(&sglq_entry->list, | 6900 | list_add_tail(&sglq_entry->list, |
6811 | &phba->sli4_hba.lpfc_sgl_list); | 6901 | &phba->sli4_hba.lpfc_sgl_list); |
6902 | sglq_entry->state = SGL_FREED; | ||
6903 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); | ||
6812 | spin_unlock_irqrestore(&phba->hbalock, iflag); | 6904 | spin_unlock_irqrestore(&phba->hbalock, iflag); |
6813 | return; | 6905 | return; |
6814 | } | 6906 | } |
6815 | } | 6907 | } |
6816 | spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); | 6908 | spin_unlock(&phba->sli4_hba.abts_sgl_list_lock); |
6909 | sglq_entry = __lpfc_get_active_sglq(phba, xri); | ||
6910 | if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) { | ||
6911 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6912 | return; | ||
6913 | } | ||
6914 | sglq_entry->state = SGL_XRI_ABORTED; | ||
6915 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
6916 | return; | ||
6817 | } | 6917 | } |