aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/scsi/lpfc/lpfc_els.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c354
1 files changed, 310 insertions, 44 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 45337cd23feb..5fbdb22c1899 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -21,6 +21,7 @@
21/* See Fibre Channel protocol T11 FC-LS for details */ 21/* See Fibre Channel protocol T11 FC-LS for details */
22#include <linux/blkdev.h> 22#include <linux/blkdev.h>
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/slab.h>
24#include <linux/interrupt.h> 25#include <linux/interrupt.h>
25 26
26#include <scsi/scsi.h> 27#include <scsi/scsi.h>
@@ -50,9 +51,6 @@ static int lpfc_issue_els_fdisc(struct lpfc_vport *vport,
50 struct lpfc_nodelist *ndlp, uint8_t retry); 51 struct lpfc_nodelist *ndlp, uint8_t retry);
51static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba, 52static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba,
52 struct lpfc_iocbq *iocb); 53 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 54
57static int lpfc_max_els_tries = 3; 55static int lpfc_max_els_tries = 3;
58 56
@@ -173,13 +171,26 @@ lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
173 * in FIP mode send FLOGI, FDISC and LOGO as FIP frames. 171 * in FIP mode send FLOGI, FDISC and LOGO as FIP frames.
174 */ 172 */
175 if ((did == Fabric_DID) && 173 if ((did == Fabric_DID) &&
176 bf_get(lpfc_fip_flag, &phba->sli4_hba.sli4_flags) && 174 (phba->hba_flag & HBA_FIP_SUPPORT) &&
177 ((elscmd == ELS_CMD_FLOGI) || 175 ((elscmd == ELS_CMD_FLOGI) ||
178 (elscmd == ELS_CMD_FDISC) || 176 (elscmd == ELS_CMD_FDISC) ||
179 (elscmd == ELS_CMD_LOGO))) 177 (elscmd == ELS_CMD_LOGO)))
180 elsiocb->iocb_flag |= LPFC_FIP_ELS; 178 switch (elscmd) {
179 case ELS_CMD_FLOGI:
180 elsiocb->iocb_flag |= ((ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
181 & LPFC_FIP_ELS_ID_MASK);
182 break;
183 case ELS_CMD_FDISC:
184 elsiocb->iocb_flag |= ((ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
185 & LPFC_FIP_ELS_ID_MASK);
186 break;
187 case ELS_CMD_LOGO:
188 elsiocb->iocb_flag |= ((ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
189 & LPFC_FIP_ELS_ID_MASK);
190 break;
191 }
181 else 192 else
182 elsiocb->iocb_flag &= ~LPFC_FIP_ELS; 193 elsiocb->iocb_flag &= ~LPFC_FIP_ELS_ID_MASK;
183 194
184 icmd = &elsiocb->iocb; 195 icmd = &elsiocb->iocb;
185 196
@@ -579,6 +590,15 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
579 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 590 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
580 spin_unlock_irq(shost->host_lock); 591 spin_unlock_irq(shost->host_lock);
581 } 592 }
593 /*
594 * If VPI is unreged, driver need to do INIT_VPI
595 * before re-registering
596 */
597 if (phba->sli_rev == LPFC_SLI_REV4) {
598 spin_lock_irq(shost->host_lock);
599 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
600 spin_unlock_irq(shost->host_lock);
601 }
582 } 602 }
583 603
584 if (phba->sli_rev < LPFC_SLI_REV4) { 604 if (phba->sli_rev < LPFC_SLI_REV4) {
@@ -591,10 +611,13 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
591 } else { 611 } else {
592 ndlp->nlp_type |= NLP_FABRIC; 612 ndlp->nlp_type |= NLP_FABRIC;
593 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 613 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
594 if (vport->vfi_state & LPFC_VFI_REGISTERED) { 614 if ((!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) &&
615 (vport->vpi_state & LPFC_VPI_REGISTERED)) {
595 lpfc_start_fdiscs(phba); 616 lpfc_start_fdiscs(phba);
596 lpfc_do_scr_ns_plogi(phba, vport); 617 lpfc_do_scr_ns_plogi(phba, vport);
597 } else 618 } else if (vport->fc_flag & FC_VFI_REGISTERED)
619 lpfc_issue_init_vpi(vport);
620 else
598 lpfc_issue_reg_vfi(vport); 621 lpfc_issue_reg_vfi(vport);
599 } 622 }
600 return 0; 623 return 0;
@@ -749,6 +772,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
749 struct lpfc_nodelist *ndlp = cmdiocb->context1; 772 struct lpfc_nodelist *ndlp = cmdiocb->context1;
750 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp; 773 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
751 struct serv_parm *sp; 774 struct serv_parm *sp;
775 uint16_t fcf_index;
752 int rc; 776 int rc;
753 777
754 /* Check to see if link went down during discovery */ 778 /* Check to see if link went down during discovery */
@@ -766,6 +790,54 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
766 vport->port_state); 790 vport->port_state);
767 791
768 if (irsp->ulpStatus) { 792 if (irsp->ulpStatus) {
793 /*
794 * In case of FIP mode, perform round robin FCF failover
795 * due to new FCF discovery
796 */
797 if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
798 (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
799 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
800 "2611 FLOGI failed on registered "
801 "FCF record fcf_index:%d, trying "
802 "to perform round robin failover\n",
803 phba->fcf.current_rec.fcf_indx);
804 fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
805 if (fcf_index == LPFC_FCOE_FCF_NEXT_NONE) {
806 /*
807 * Exhausted the eligible FCF record list,
808 * fail through to retry FLOGI on current
809 * FCF record.
810 */
811 lpfc_printf_log(phba, KERN_WARNING,
812 LOG_FIP | LOG_ELS,
813 "2760 FLOGI exhausted FCF "
814 "round robin failover list, "
815 "retry FLOGI on the current "
816 "registered FCF index:%d\n",
817 phba->fcf.current_rec.fcf_indx);
818 spin_lock_irq(&phba->hbalock);
819 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
820 spin_unlock_irq(&phba->hbalock);
821 } else {
822 rc = lpfc_sli4_fcf_rr_read_fcf_rec(phba,
823 fcf_index);
824 if (rc) {
825 lpfc_printf_log(phba, KERN_WARNING,
826 LOG_FIP | LOG_ELS,
827 "2761 FLOGI round "
828 "robin FCF failover "
829 "read FCF failed "
830 "rc:x%x, fcf_index:"
831 "%d\n", rc,
832 phba->fcf.current_rec.fcf_indx);
833 spin_lock_irq(&phba->hbalock);
834 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
835 spin_unlock_irq(&phba->hbalock);
836 } else
837 goto out;
838 }
839 }
840
769 /* Check for retry */ 841 /* Check for retry */
770 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) 842 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
771 goto out; 843 goto out;
@@ -784,13 +856,15 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
784 } 856 }
785 857
786 /* FLOGI failure */ 858 /* FLOGI failure */
787 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 859 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
788 "0100 FLOGI failure Data: x%x x%x " 860 "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
789 "x%x\n",
790 irsp->ulpStatus, irsp->un.ulpWord[4], 861 irsp->ulpStatus, irsp->un.ulpWord[4],
791 irsp->ulpTimeout); 862 irsp->ulpTimeout);
792 goto flogifail; 863 goto flogifail;
793 } 864 }
865 spin_lock_irq(shost->host_lock);
866 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
867 spin_unlock_irq(shost->host_lock);
794 868
795 /* 869 /*
796 * The FLogI succeeded. Sync the data for the CPU before 870 * The FLogI succeeded. Sync the data for the CPU before
@@ -802,7 +876,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
802 876
803 /* FLOGI completes successfully */ 877 /* FLOGI completes successfully */
804 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, 878 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
805 "0101 FLOGI completes sucessfully " 879 "0101 FLOGI completes successfully "
806 "Data: x%x x%x x%x x%x\n", 880 "Data: x%x x%x x%x x%x\n",
807 irsp->un.ulpWord[4], sp->cmn.e_d_tov, 881 irsp->un.ulpWord[4], sp->cmn.e_d_tov,
808 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution); 882 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
@@ -817,8 +891,18 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
817 else 891 else
818 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp); 892 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
819 893
820 if (!rc) 894 if (!rc) {
895 /* Mark the FCF discovery process done */
896 lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP | LOG_ELS,
897 "2769 FLOGI successful on FCF record: "
898 "current_fcf_index:x%x, terminate FCF "
899 "round robin failover process\n",
900 phba->fcf.current_rec.fcf_indx);
901 spin_lock_irq(&phba->hbalock);
902 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
903 spin_unlock_irq(&phba->hbalock);
821 goto out; 904 goto out;
905 }
822 } 906 }
823 907
824flogifail: 908flogifail:
@@ -956,7 +1040,7 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
956 * function returns, it does not guarantee all the IOCBs are actually aborted. 1040 * function returns, it does not guarantee all the IOCBs are actually aborted.
957 * 1041 *
958 * Return code 1042 * Return code
959 * 0 - Sucessfully issued abort iocb on all outstanding flogis (Always 0) 1043 * 0 - Successfully issued abort iocb on all outstanding flogis (Always 0)
960 **/ 1044 **/
961int 1045int
962lpfc_els_abort_flogi(struct lpfc_hba *phba) 1046lpfc_els_abort_flogi(struct lpfc_hba *phba)
@@ -1384,6 +1468,10 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1384 goto out; 1468 goto out;
1385 } 1469 }
1386 /* PLOGI failed */ 1470 /* PLOGI failed */
1471 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1472 "2753 PLOGI failure DID:%06X Status:x%x/x%x\n",
1473 ndlp->nlp_DID, irsp->ulpStatus,
1474 irsp->un.ulpWord[4]);
1387 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1475 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1388 if (lpfc_error_lost_link(irsp)) 1476 if (lpfc_error_lost_link(irsp))
1389 rc = NLP_STE_FREED_NODE; 1477 rc = NLP_STE_FREED_NODE;
@@ -1552,6 +1640,10 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1552 goto out; 1640 goto out;
1553 } 1641 }
1554 /* PRLI failed */ 1642 /* PRLI failed */
1643 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1644 "2754 PRLI failure DID:%06X Status:x%x/x%x\n",
1645 ndlp->nlp_DID, irsp->ulpStatus,
1646 irsp->un.ulpWord[4]);
1555 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1647 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1556 if (lpfc_error_lost_link(irsp)) 1648 if (lpfc_error_lost_link(irsp))
1557 goto out; 1649 goto out;
@@ -1835,6 +1927,10 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1835 goto out; 1927 goto out;
1836 } 1928 }
1837 /* ADISC failed */ 1929 /* ADISC failed */
1930 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1931 "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
1932 ndlp->nlp_DID, irsp->ulpStatus,
1933 irsp->un.ulpWord[4]);
1838 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 1934 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1839 if (!lpfc_error_lost_link(irsp)) 1935 if (!lpfc_error_lost_link(irsp))
1840 lpfc_disc_state_machine(vport, ndlp, cmdiocb, 1936 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
@@ -1984,6 +2080,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1984 /* ELS command is being retried */ 2080 /* ELS command is being retried */
1985 goto out; 2081 goto out;
1986 /* LOGO failed */ 2082 /* LOGO failed */
2083 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2084 "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
2085 ndlp->nlp_DID, irsp->ulpStatus,
2086 irsp->un.ulpWord[4]);
1987 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 2087 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
1988 if (lpfc_error_lost_link(irsp)) 2088 if (lpfc_error_lost_link(irsp))
1989 goto out; 2089 goto out;
@@ -2452,6 +2552,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
2452 */ 2552 */
2453 del_timer_sync(&ndlp->nlp_delayfunc); 2553 del_timer_sync(&ndlp->nlp_delayfunc);
2454 retry = ndlp->nlp_retry; 2554 retry = ndlp->nlp_retry;
2555 ndlp->nlp_retry = 0;
2455 2556
2456 switch (cmd) { 2557 switch (cmd) {
2457 case ELS_CMD_FLOGI: 2558 case ELS_CMD_FLOGI:
@@ -2706,17 +2807,21 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2706 if (did == FDMI_DID) 2807 if (did == FDMI_DID)
2707 retry = 1; 2808 retry = 1;
2708 2809
2709 if ((cmd == ELS_CMD_FLOGI) && 2810 if (((cmd == ELS_CMD_FLOGI) || (cmd == ELS_CMD_FDISC)) &&
2710 (phba->fc_topology != TOPOLOGY_LOOP) && 2811 (phba->fc_topology != TOPOLOGY_LOOP) &&
2711 !lpfc_error_lost_link(irsp)) { 2812 !lpfc_error_lost_link(irsp)) {
2712 /* FLOGI retry policy */ 2813 /* FLOGI retry policy */
2713 retry = 1; 2814 retry = 1;
2714 maxretry = 48; 2815 /* retry forever */
2715 if (cmdiocb->retry >= 32) 2816 maxretry = 0;
2817 if (cmdiocb->retry >= 100)
2818 delay = 5000;
2819 else if (cmdiocb->retry >= 32)
2716 delay = 1000; 2820 delay = 1000;
2717 } 2821 }
2718 2822
2719 if ((++cmdiocb->retry) >= maxretry) { 2823 cmdiocb->retry++;
2824 if (maxretry && (cmdiocb->retry >= maxretry)) {
2720 phba->fc_stat.elsRetryExceeded++; 2825 phba->fc_stat.elsRetryExceeded++;
2721 retry = 0; 2826 retry = 0;
2722 } 2827 }
@@ -3099,7 +3204,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
3099 if (ndlp && NLP_CHK_NODE_ACT(ndlp) && 3204 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
3100 (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) { 3205 (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
3101 /* A LS_RJT associated with Default RPI cleanup has its own 3206 /* A LS_RJT associated with Default RPI cleanup has its own
3102 * seperate code path. 3207 * separate code path.
3103 */ 3208 */
3104 if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI)) 3209 if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
3105 ls_rjt = 1; 3210 ls_rjt = 1;
@@ -4124,8 +4229,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4124 spin_lock_irq(shost->host_lock); 4229 spin_lock_irq(shost->host_lock);
4125 if (vport->fc_rscn_flush) { 4230 if (vport->fc_rscn_flush) {
4126 /* Another thread is walking fc_rscn_id_list on this vport */ 4231 /* Another thread is walking fc_rscn_id_list on this vport */
4127 spin_unlock_irq(shost->host_lock);
4128 vport->fc_flag |= FC_RSCN_DISCOVERY; 4232 vport->fc_flag |= FC_RSCN_DISCOVERY;
4233 spin_unlock_irq(shost->host_lock);
4129 /* Send back ACC */ 4234 /* Send back ACC */
4130 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 4235 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4131 return 0; 4236 return 0;
@@ -4133,7 +4238,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4133 /* Indicate we are walking fc_rscn_id_list on this vport */ 4238 /* Indicate we are walking fc_rscn_id_list on this vport */
4134 vport->fc_rscn_flush = 1; 4239 vport->fc_rscn_flush = 1;
4135 spin_unlock_irq(shost->host_lock); 4240 spin_unlock_irq(shost->host_lock);
4136 /* Get the array count after sucessfully have the token */ 4241 /* Get the array count after successfully have the token */
4137 rscn_cnt = vport->fc_rscn_id_cnt; 4242 rscn_cnt = vport->fc_rscn_id_cnt;
4138 /* If we are already processing an RSCN, save the received 4243 /* If we are already processing an RSCN, save the received
4139 * RSCN payload buffer, cmdiocb->context2 to process later. 4244 * RSCN payload buffer, cmdiocb->context2 to process later.
@@ -4367,7 +4472,7 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4367 4472
4368 did = Fabric_DID; 4473 did = Fabric_DID;
4369 4474
4370 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) { 4475 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
4371 /* For a FLOGI we accept, then if our portname is greater 4476 /* For a FLOGI we accept, then if our portname is greater
4372 * then the remote portname we initiate Nport login. 4477 * then the remote portname we initiate Nport login.
4373 */ 4478 */
@@ -4503,6 +4608,29 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4503} 4608}
4504 4609
4505/** 4610/**
4611 * lpfc_els_rcv_rrq - Process an unsolicited rrq iocb
4612 * @vport: pointer to a host virtual N_Port data structure.
4613 * @cmdiocb: pointer to lpfc command iocb data structure.
4614 * @ndlp: pointer to a node-list data structure.
4615 *
4616 * This routine processes a Reinstate Recovery Qualifier (RRQ) IOCB
4617 * received as an ELS unsolicited event. A request to RRQ shall only
4618 * be accepted if the Originator Nx_Port N_Port_ID or the Responder
4619 * Nx_Port N_Port_ID of the target Exchange is the same as the
4620 * N_Port_ID of the Nx_Port that makes the request. If the RRQ is
4621 * not accepted, an LS_RJT with reason code "Unable to perform
4622 * command request" and reason code explanation "Invalid Originator
4623 * S_ID" shall be returned. For now, we just unconditionally accept
4624 * RRQ from the target.
4625 **/
4626static void
4627lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4628 struct lpfc_nodelist *ndlp)
4629{
4630 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4631}
4632
4633/**
4506 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd 4634 * lpfc_els_rsp_rps_acc - Completion callbk func for MBX_READ_LNK_STAT mbox cmd
4507 * @phba: pointer to lpfc hba data structure. 4635 * @phba: pointer to lpfc hba data structure.
4508 * @pmb: pointer to the driver internal queue element for mailbox command. 4636 * @pmb: pointer to the driver internal queue element for mailbox command.
@@ -5396,7 +5524,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5396 if (lpfc_els_chk_latt(vport)) 5524 if (lpfc_els_chk_latt(vport))
5397 goto dropit; 5525 goto dropit;
5398 5526
5399 /* Ignore traffic recevied during vport shutdown. */ 5527 /* Ignore traffic received during vport shutdown. */
5400 if (vport->load_flag & FC_UNLOADING) 5528 if (vport->load_flag & FC_UNLOADING)
5401 goto dropit; 5529 goto dropit;
5402 5530
@@ -5618,6 +5746,16 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5618 if (newnode) 5746 if (newnode)
5619 lpfc_nlp_put(ndlp); 5747 lpfc_nlp_put(ndlp);
5620 break; 5748 break;
5749 case ELS_CMD_RRQ:
5750 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5751 "RCV RRQ: did:x%x/ste:x%x flg:x%x",
5752 did, vport->port_state, ndlp->nlp_flag);
5753
5754 phba->fc_stat.elsRcvRRQ++;
5755 lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
5756 if (newnode)
5757 lpfc_nlp_put(ndlp);
5758 break;
5621 default: 5759 default:
5622 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, 5760 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5623 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", 5761 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
@@ -5670,7 +5808,7 @@ dropit:
5670 * NULL - No vport with the matching @vpi found 5808 * NULL - No vport with the matching @vpi found
5671 * Otherwise - Address to the vport with the matching @vpi. 5809 * Otherwise - Address to the vport with the matching @vpi.
5672 **/ 5810 **/
5673static struct lpfc_vport * 5811struct lpfc_vport *
5674lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi) 5812lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
5675{ 5813{
5676 struct lpfc_vport *vport; 5814 struct lpfc_vport *vport;
@@ -5864,6 +6002,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5864 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 6002 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5865 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; 6003 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
5866 MAILBOX_t *mb = &pmb->u.mb; 6004 MAILBOX_t *mb = &pmb->u.mb;
6005 int rc;
5867 6006
5868 spin_lock_irq(shost->host_lock); 6007 spin_lock_irq(shost->host_lock);
5869 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI; 6008 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
@@ -5885,6 +6024,26 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5885 spin_unlock_irq(shost->host_lock); 6024 spin_unlock_irq(shost->host_lock);
5886 lpfc_can_disctmo(vport); 6025 lpfc_can_disctmo(vport);
5887 break; 6026 break;
6027 /* If reg_vpi fail with invalid VPI status, re-init VPI */
6028 case 0x20:
6029 spin_lock_irq(shost->host_lock);
6030 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
6031 spin_unlock_irq(shost->host_lock);
6032 lpfc_init_vpi(phba, pmb, vport->vpi);
6033 pmb->vport = vport;
6034 pmb->mbox_cmpl = lpfc_init_vpi_cmpl;
6035 rc = lpfc_sli_issue_mbox(phba, pmb,
6036 MBX_NOWAIT);
6037 if (rc == MBX_NOT_FINISHED) {
6038 lpfc_printf_vlog(vport,
6039 KERN_ERR, LOG_MBOX,
6040 "2732 Failed to issue INIT_VPI"
6041 " mailbox command\n");
6042 } else {
6043 lpfc_nlp_put(ndlp);
6044 return;
6045 }
6046
5888 default: 6047 default:
5889 /* Try to recover from this error */ 6048 /* Try to recover from this error */
5890 lpfc_mbx_unreg_vpi(vport); 6049 lpfc_mbx_unreg_vpi(vport);
@@ -5897,14 +6056,23 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5897 lpfc_initial_fdisc(vport); 6056 lpfc_initial_fdisc(vport);
5898 break; 6057 break;
5899 } 6058 }
5900
5901 } else { 6059 } else {
5902 if (vport == phba->pport) 6060 spin_lock_irq(shost->host_lock);
6061 vport->vpi_state |= LPFC_VPI_REGISTERED;
6062 spin_unlock_irq(shost->host_lock);
6063 if (vport == phba->pport) {
5903 if (phba->sli_rev < LPFC_SLI_REV4) 6064 if (phba->sli_rev < LPFC_SLI_REV4)
5904 lpfc_issue_fabric_reglogin(vport); 6065 lpfc_issue_fabric_reglogin(vport);
5905 else 6066 else {
5906 lpfc_issue_reg_vfi(vport); 6067 /*
5907 else 6068 * If the physical port is instantiated using
6069 * FDISC, do not start vport discovery.
6070 */
6071 if (vport->port_state != LPFC_FDISC)
6072 lpfc_start_fdiscs(phba);
6073 lpfc_do_scr_ns_plogi(phba, vport);
6074 }
6075 } else
5908 lpfc_do_scr_ns_plogi(phba, vport); 6076 lpfc_do_scr_ns_plogi(phba, vport);
5909 } 6077 }
5910 6078
@@ -5926,7 +6094,7 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5926 * This routine registers the @vport as a new virtual port with a HBA. 6094 * This routine registers the @vport as a new virtual port with a HBA.
5927 * It is done through a registering vpi mailbox command. 6095 * It is done through a registering vpi mailbox command.
5928 **/ 6096 **/
5929static void 6097void
5930lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport, 6098lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
5931 struct lpfc_nodelist *ndlp) 6099 struct lpfc_nodelist *ndlp)
5932{ 6100{
@@ -5967,6 +6135,92 @@ mbox_err_exit:
5967} 6135}
5968 6136
5969/** 6137/**
6138 * lpfc_cancel_all_vport_retry_delay_timer - Cancel all vport retry delay timer
6139 * @phba: pointer to lpfc hba data structure.
6140 *
6141 * This routine cancels the retry delay timers to all the vports.
6142 **/
6143void
6144lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
6145{
6146 struct lpfc_vport **vports;
6147 struct lpfc_nodelist *ndlp;
6148 uint32_t link_state;
6149 int i;
6150
6151 /* Treat this failure as linkdown for all vports */
6152 link_state = phba->link_state;
6153 lpfc_linkdown(phba);
6154 phba->link_state = link_state;
6155
6156 vports = lpfc_create_vport_work_array(phba);
6157
6158 if (vports) {
6159 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
6160 ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
6161 if (ndlp)
6162 lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
6163 lpfc_els_flush_cmd(vports[i]);
6164 }
6165 lpfc_destroy_vport_work_array(phba, vports);
6166 }
6167}
6168
6169/**
6170 * lpfc_retry_pport_discovery - Start timer to retry FLOGI.
6171 * @phba: pointer to lpfc hba data structure.
6172 *
6173 * This routine abort all pending discovery commands and
6174 * start a timer to retry FLOGI for the physical port
6175 * discovery.
6176 **/
6177void
6178lpfc_retry_pport_discovery(struct lpfc_hba *phba)
6179{
6180 struct lpfc_nodelist *ndlp;
6181 struct Scsi_Host *shost;
6182
6183 /* Cancel the all vports retry delay retry timers */
6184 lpfc_cancel_all_vport_retry_delay_timer(phba);
6185
6186 /* If fabric require FLOGI, then re-instantiate physical login */
6187 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
6188 if (!ndlp)
6189 return;
6190
6191 shost = lpfc_shost_from_vport(phba->pport);
6192 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
6193 spin_lock_irq(shost->host_lock);
6194 ndlp->nlp_flag |= NLP_DELAY_TMO;
6195 spin_unlock_irq(shost->host_lock);
6196 ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
6197 phba->pport->port_state = LPFC_FLOGI;
6198 return;
6199}
6200
6201/**
6202 * lpfc_fabric_login_reqd - Check if FLOGI required.
6203 * @phba: pointer to lpfc hba data structure.
6204 * @cmdiocb: pointer to FDISC command iocb.
6205 * @rspiocb: pointer to FDISC response iocb.
6206 *
6207 * This routine checks if a FLOGI is reguired for FDISC
6208 * to succeed.
6209 **/
6210static int
6211lpfc_fabric_login_reqd(struct lpfc_hba *phba,
6212 struct lpfc_iocbq *cmdiocb,
6213 struct lpfc_iocbq *rspiocb)
6214{
6215
6216 if ((rspiocb->iocb.ulpStatus != IOSTAT_FABRIC_RJT) ||
6217 (rspiocb->iocb.un.ulpWord[4] != RJT_LOGIN_REQUIRED))
6218 return 0;
6219 else
6220 return 1;
6221}
6222
6223/**
5970 * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command 6224 * lpfc_cmpl_els_fdisc - Completion function for fdisc iocb command
5971 * @phba: pointer to lpfc hba data structure. 6225 * @phba: pointer to lpfc hba data structure.
5972 * @cmdiocb: pointer to lpfc command iocb data structure. 6226 * @cmdiocb: pointer to lpfc command iocb data structure.
@@ -6015,6 +6269,12 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6015 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID); 6269 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
6016 6270
6017 if (irsp->ulpStatus) { 6271 if (irsp->ulpStatus) {
6272
6273 if (lpfc_fabric_login_reqd(phba, cmdiocb, rspiocb)) {
6274 lpfc_retry_pport_discovery(phba);
6275 goto out;
6276 }
6277
6018 /* Check for retry */ 6278 /* Check for retry */
6019 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) 6279 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
6020 goto out; 6280 goto out;
@@ -6024,12 +6284,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6024 irsp->ulpStatus, irsp->un.ulpWord[4]); 6284 irsp->ulpStatus, irsp->un.ulpWord[4]);
6025 goto fdisc_failed; 6285 goto fdisc_failed;
6026 } 6286 }
6027 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
6028 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
6029 lpfc_nlp_put(ndlp);
6030 /* giving up on FDISC. Cancel discovery timer */
6031 lpfc_can_disctmo(vport);
6032 spin_lock_irq(shost->host_lock); 6287 spin_lock_irq(shost->host_lock);
6288 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
6033 vport->fc_flag |= FC_FABRIC; 6289 vport->fc_flag |= FC_FABRIC;
6034 if (vport->phba->fc_topology == TOPOLOGY_LOOP) 6290 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
6035 vport->fc_flag |= FC_PUBLIC_LOOP; 6291 vport->fc_flag |= FC_PUBLIC_LOOP;
@@ -6057,10 +6313,14 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6057 lpfc_mbx_unreg_vpi(vport); 6313 lpfc_mbx_unreg_vpi(vport);
6058 spin_lock_irq(shost->host_lock); 6314 spin_lock_irq(shost->host_lock);
6059 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6315 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
6316 if (phba->sli_rev == LPFC_SLI_REV4)
6317 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
6060 spin_unlock_irq(shost->host_lock); 6318 spin_unlock_irq(shost->host_lock);
6061 } 6319 }
6062 6320
6063 if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) 6321 if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)
6322 lpfc_issue_init_vpi(vport);
6323 else if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
6064 lpfc_register_new_vport(phba, vport, ndlp); 6324 lpfc_register_new_vport(phba, vport, ndlp);
6065 else 6325 else
6066 lpfc_do_scr_ns_plogi(phba, vport); 6326 lpfc_do_scr_ns_plogi(phba, vport);
@@ -6107,6 +6367,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6107 int did = ndlp->nlp_DID; 6367 int did = ndlp->nlp_DID;
6108 int rc; 6368 int rc;
6109 6369
6370 vport->port_state = LPFC_FDISC;
6110 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); 6371 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
6111 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, 6372 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
6112 ELS_CMD_FDISC); 6373 ELS_CMD_FDISC);
@@ -6172,7 +6433,6 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
6172 return 1; 6433 return 1;
6173 } 6434 }
6174 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING); 6435 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
6175 vport->port_state = LPFC_FDISC;
6176 return 0; 6436 return 0;
6177} 6437}
6178 6438
@@ -6632,21 +6892,27 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
6632 struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL; 6892 struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
6633 unsigned long iflag = 0; 6893 unsigned long iflag = 0;
6634 6894
6635 spin_lock_irqsave(&phba->sli4_hba.abts_sgl_list_lock, iflag); 6895 spin_lock_irqsave(&phba->hbalock, iflag);
6896 spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
6636 list_for_each_entry_safe(sglq_entry, sglq_next, 6897 list_for_each_entry_safe(sglq_entry, sglq_next,
6637 &phba->sli4_hba.lpfc_abts_els_sgl_list, list) { 6898 &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
6638 if (sglq_entry->sli4_xritag == xri) { 6899 if (sglq_entry->sli4_xritag == xri) {
6639 list_del(&sglq_entry->list); 6900 list_del(&sglq_entry->list);
6640 spin_unlock_irqrestore(
6641 &phba->sli4_hba.abts_sgl_list_lock,
6642 iflag);
6643 spin_lock_irqsave(&phba->hbalock, iflag);
6644
6645 list_add_tail(&sglq_entry->list, 6901 list_add_tail(&sglq_entry->list,
6646 &phba->sli4_hba.lpfc_sgl_list); 6902 &phba->sli4_hba.lpfc_sgl_list);
6903 sglq_entry->state = SGL_FREED;
6904 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
6647 spin_unlock_irqrestore(&phba->hbalock, iflag); 6905 spin_unlock_irqrestore(&phba->hbalock, iflag);
6648 return; 6906 return;
6649 } 6907 }
6650 } 6908 }
6651 spin_unlock_irqrestore(&phba->sli4_hba.abts_sgl_list_lock, iflag); 6909 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
6910 sglq_entry = __lpfc_get_active_sglq(phba, xri);
6911 if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
6912 spin_unlock_irqrestore(&phba->hbalock, iflag);
6913 return;
6914 }
6915 sglq_entry->state = SGL_XRI_ABORTED;
6916 spin_unlock_irqrestore(&phba->hbalock, iflag);
6917 return;
6652} 6918}