aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 19:54:31 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-18 19:54:31 -0400
commit961cde93dee2658000ead32abffb8ddf0727abe0 (patch)
tree2419e204132abe2ec2bb7f08bd20042573cc9bd6 /drivers/scsi/lpfc/lpfc_els.c
parentf82c37e7bb4c4d9b6a476c642d5c2d2efbd6f240 (diff)
parent0d9dc7c8b9b7fa0f53647423b41056ee1beed735 (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.c142
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
849flogifail: 907flogifail:
@@ -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 **/
6065void 6142void
6066lpfc_retry_pport_discovery(struct lpfc_hba *phba) 6143lpfc_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 **/
6176void
6177lpfc_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}