aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2007-10-27 13:37:43 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:33 -0500
commit87af33fe5f78c27cf9e43c6e586dd6efd4be3e40 (patch)
treee9960c6e95ed599672d5dcec0d3c4e428ae42799 /drivers/scsi/lpfc
parent98c9ea5c026ee47efe2a0f595078dbf199d08f50 (diff)
[SCSI] lpfc 8.2.3 : FC Discovery Fixes
FC Discovery Fixes: - Fix up lpfc_drop_node() vs lpfc_nlp_not_used() usage - Clear ADISC flag when unregistering RPI and REMOVE ndlps if in recovery. - Fix usage of UNUSED list and ndlps - Fix PLOGI race conditions - Reset link if NameServer PLOGI errors occur - Synchronize GID_FT queries with PLOGI receptions Signed-off-by: James Smart <James.Smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc_crtn.h4
-rw-r--r--drivers/scsi/lpfc/lpfc_disc.h1
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c231
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c96
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c66
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c82
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c24
7 files changed, 300 insertions, 204 deletions
diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h
index 59164c6aa28f..338b5dd10a92 100644
--- a/drivers/scsi/lpfc/lpfc_crtn.h
+++ b/drivers/scsi/lpfc/lpfc_crtn.h
@@ -45,6 +45,7 @@ void lpfc_init_link(struct lpfc_hba *, LPFC_MBOXQ_t *, uint32_t, uint32_t);
45struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t); 45struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
46void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove); 46void lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove);
47int lpfc_linkdown(struct lpfc_hba *); 47int lpfc_linkdown(struct lpfc_hba *);
48void lpfc_port_link_failure(struct lpfc_vport *);
48void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *); 49void lpfc_mbx_cmpl_read_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
49 50
50void lpfc_mbx_cmpl_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *); 51void lpfc_mbx_cmpl_clear_la(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -74,6 +75,7 @@ void lpfc_disc_list_loopmap(struct lpfc_vport *);
74void lpfc_disc_start(struct lpfc_vport *); 75void lpfc_disc_start(struct lpfc_vport *);
75void lpfc_disc_flush_list(struct lpfc_vport *); 76void lpfc_disc_flush_list(struct lpfc_vport *);
76void lpfc_cleanup_discovery_resources(struct lpfc_vport *); 77void lpfc_cleanup_discovery_resources(struct lpfc_vport *);
78void lpfc_cleanup(struct lpfc_vport *);
77void lpfc_disc_timeout(unsigned long); 79void lpfc_disc_timeout(unsigned long);
78 80
79struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t); 81struct lpfc_nodelist *__lpfc_findnode_rpi(struct lpfc_vport *, uint16_t);
@@ -91,6 +93,8 @@ void lpfc_do_scr_ns_plogi(struct lpfc_hba *, struct lpfc_vport *);
91int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *, 93int lpfc_check_sparm(struct lpfc_vport *, struct lpfc_nodelist *,
92 struct serv_parm *, uint32_t); 94 struct serv_parm *, uint32_t);
93int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *); 95int lpfc_els_abort(struct lpfc_hba *, struct lpfc_nodelist *);
96void lpfc_more_plogi(struct lpfc_vport *);
97void lpfc_end_rscn(struct lpfc_vport *);
94int lpfc_els_chk_latt(struct lpfc_vport *); 98int lpfc_els_chk_latt(struct lpfc_vport *);
95int lpfc_els_abort_flogi(struct lpfc_hba *); 99int lpfc_els_abort_flogi(struct lpfc_hba *);
96int lpfc_initial_flogi(struct lpfc_vport *); 100int lpfc_initial_flogi(struct lpfc_vport *);
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h
index c9422a8423ca..99bc1a1ecac2 100644
--- a/drivers/scsi/lpfc/lpfc_disc.h
+++ b/drivers/scsi/lpfc/lpfc_disc.h
@@ -103,7 +103,6 @@ struct lpfc_nodelist {
103#define NLP_RM_DFLT_RPI 0x4000000 /* need to remove leftover dflt RPI */ 103#define NLP_RM_DFLT_RPI 0x4000000 /* need to remove leftover dflt RPI */
104#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ 104#define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */
105#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */ 105#define NLP_TARGET_REMOVE 0x10000000 /* Target remove in process */
106#define NLP_DELAYED_RM 0x20000000 /* Defer UNUSED List removal */
107 106
108/* There are 4 different double linked lists nodelist entries can reside on. 107/* There are 4 different double linked lists nodelist entries can reside on.
109 * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used 108 * The Port Login (PLOGI) list and Address Discovery (ADISC) list are used
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 813eeca7ce1e..0a5006ea9909 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -575,8 +575,13 @@ flogifail:
575 575
576 /* Start discovery */ 576 /* Start discovery */
577 lpfc_disc_start(vport); 577 lpfc_disc_start(vport);
578 } else if (((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
579 ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
580 (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) &&
581 (phba->link_state != LPFC_CLEAR_LA)) {
582 /* If FLOGI failed enable link interrupt. */
583 lpfc_issue_clear_la(phba, vport);
578 } 584 }
579
580out: 585out:
581 lpfc_els_free_iocb(phba, cmdiocb); 586 lpfc_els_free_iocb(phba, cmdiocb);
582} 587}
@@ -711,13 +716,8 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
711 lpfc_nlp_init(vport, ndlp, Fabric_DID); 716 lpfc_nlp_init(vport, ndlp, Fabric_DID);
712 } else { 717 } else {
713 lpfc_dequeue_node(vport, ndlp); 718 lpfc_dequeue_node(vport, ndlp);
714
715 /* If we go thru this path, Fabric_DID ndlp is in the process
716 * of being removed. We need to bump the reference count by 1
717 * so it stays around all through this link up period.
718 */
719 lpfc_nlp_get(ndlp);
720 } 719 }
720
721 if (lpfc_issue_els_flogi(vport, ndlp, 0)) { 721 if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
722 lpfc_nlp_put(ndlp); 722 lpfc_nlp_put(ndlp);
723 } 723 }
@@ -746,7 +746,8 @@ lpfc_initial_fdisc(struct lpfc_vport *vport)
746 } 746 }
747 return 1; 747 return 1;
748} 748}
749static void 749
750void
750lpfc_more_plogi(struct lpfc_vport *vport) 751lpfc_more_plogi(struct lpfc_vport *vport)
751{ 752{
752 int sentplogi; 753 int sentplogi;
@@ -813,8 +814,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
813 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state); 814 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
814 815
815 /* Move this back to NPR state */ 816 /* Move this back to NPR state */
816 if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) 817 if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
818 /* The new_ndlp is replacing ndlp totally, so we need
819 * to put ndlp on UNUSED list and try to free it.
820 */
817 lpfc_drop_node(vport, ndlp); 821 lpfc_drop_node(vport, ndlp);
822 }
818 else { 823 else {
819 lpfc_unreg_rpi(vport, ndlp); 824 lpfc_unreg_rpi(vport, ndlp);
820 ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */ 825 ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
@@ -823,6 +828,27 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
823 return new_ndlp; 828 return new_ndlp;
824} 829}
825 830
831void
832lpfc_end_rscn(struct lpfc_vport *vport)
833{
834 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
835
836 if (vport->fc_flag & FC_RSCN_MODE) {
837 /*
838 * Check to see if more RSCNs came in while we were
839 * processing this one.
840 */
841 if (vport->fc_rscn_id_cnt ||
842 (vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
843 lpfc_els_handle_rscn(vport);
844 else {
845 spin_lock_irq(shost->host_lock);
846 vport->fc_flag &= ~FC_RSCN_MODE;
847 spin_unlock_irq(shost->host_lock);
848 }
849 }
850}
851
826static void 852static void
827lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, 853lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
828 struct lpfc_iocbq *rspiocb) 854 struct lpfc_iocbq *rspiocb)
@@ -893,13 +919,6 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
893 goto out; 919 goto out;
894 } 920 }
895 /* PLOGI failed */ 921 /* PLOGI failed */
896 if (ndlp->nlp_DID == NameServer_DID) {
897 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
898 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
899 "0250 Nameserver login error: "
900 "0x%x / 0x%x\n",
901 irsp->ulpStatus, irsp->un.ulpWord[4]);
902 }
903 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ 922 /* Do not call DSM for lpfc_els_abort'ed ELS cmds */
904 if (lpfc_error_lost_link(irsp)) { 923 if (lpfc_error_lost_link(irsp)) {
905 rc = NLP_STE_FREED_NODE; 924 rc = NLP_STE_FREED_NODE;
@@ -927,20 +946,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
927 spin_unlock_irq(shost->host_lock); 946 spin_unlock_irq(shost->host_lock);
928 947
929 lpfc_can_disctmo(vport); 948 lpfc_can_disctmo(vport);
930 if (vport->fc_flag & FC_RSCN_MODE) { 949 lpfc_end_rscn(vport);
931 /*
932 * Check to see if more RSCNs came in while
933 * we were processing this one.
934 */
935 if ((vport->fc_rscn_id_cnt == 0) &&
936 (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
937 spin_lock_irq(shost->host_lock);
938 vport->fc_flag &= ~FC_RSCN_MODE;
939 spin_unlock_irq(shost->host_lock);
940 } else {
941 lpfc_els_handle_rscn(vport);
942 }
943 }
944 } 950 }
945 } 951 }
946 952
@@ -1160,8 +1166,6 @@ lpfc_more_adisc(struct lpfc_vport *vport)
1160static void 1166static void
1161lpfc_rscn_disc(struct lpfc_vport *vport) 1167lpfc_rscn_disc(struct lpfc_vport *vport)
1162{ 1168{
1163 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1164
1165 lpfc_can_disctmo(vport); 1169 lpfc_can_disctmo(vport);
1166 1170
1167 /* RSCN discovery */ 1171 /* RSCN discovery */
@@ -1170,19 +1174,7 @@ lpfc_rscn_disc(struct lpfc_vport *vport)
1170 if (lpfc_els_disc_plogi(vport)) 1174 if (lpfc_els_disc_plogi(vport))
1171 return; 1175 return;
1172 1176
1173 if (vport->fc_flag & FC_RSCN_MODE) { 1177 lpfc_end_rscn(vport);
1174 /* Check to see if more RSCNs came in while we were
1175 * processing this one.
1176 */
1177 if ((vport->fc_rscn_id_cnt == 0) &&
1178 (!(vport->fc_flag & FC_RSCN_DISCOVERY))) {
1179 spin_lock_irq(shost->host_lock);
1180 vport->fc_flag &= ~FC_RSCN_MODE;
1181 spin_unlock_irq(shost->host_lock);
1182 } else {
1183 lpfc_els_handle_rscn(vport);
1184 }
1185 }
1186} 1178}
1187 1179
1188static void 1180static void
@@ -1632,27 +1624,6 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
1632 return 0; 1624 return 0;
1633} 1625}
1634 1626
1635static void
1636lpfc_end_rscn(struct lpfc_vport *vport)
1637{
1638 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1639
1640 if (vport->fc_flag & FC_RSCN_MODE) {
1641 /*
1642 * Check to see if more RSCNs came in while we were
1643 * processing this one.
1644 */
1645 if (vport->fc_rscn_id_cnt ||
1646 (vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
1647 lpfc_els_handle_rscn(vport);
1648 else {
1649 spin_lock_irq(shost->host_lock);
1650 vport->fc_flag &= ~FC_RSCN_MODE;
1651 spin_unlock_irq(shost->host_lock);
1652 }
1653 }
1654}
1655
1656void 1627void
1657lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp) 1628lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
1658{ 1629{
@@ -2069,6 +2040,32 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2069} 2040}
2070 2041
2071int 2042int
2043lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
2044{
2045 struct lpfc_dmabuf *buf_ptr;
2046
2047 /* Free the response before processing the command. */
2048 if (!list_empty(&buf_ptr1->list)) {
2049 list_remove_head(&buf_ptr1->list, buf_ptr,
2050 struct lpfc_dmabuf,
2051 list);
2052 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
2053 kfree(buf_ptr);
2054 }
2055 lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys);
2056 kfree(buf_ptr1);
2057 return 0;
2058}
2059
2060int
2061lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr)
2062{
2063 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
2064 kfree(buf_ptr);
2065 return 0;
2066}
2067
2068int
2072lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb) 2069lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
2073{ 2070{
2074 struct lpfc_dmabuf *buf_ptr, *buf_ptr1; 2071 struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
@@ -2080,22 +2077,12 @@ lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
2080 /* context2 = cmd, context2->next = rsp, context3 = bpl */ 2077 /* context2 = cmd, context2->next = rsp, context3 = bpl */
2081 if (elsiocb->context2) { 2078 if (elsiocb->context2) {
2082 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; 2079 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2;
2083 /* Free the response before processing the command. */ 2080 lpfc_els_free_data(phba, buf_ptr1);
2084 if (!list_empty(&buf_ptr1->list)) {
2085 list_remove_head(&buf_ptr1->list, buf_ptr,
2086 struct lpfc_dmabuf,
2087 list);
2088 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
2089 kfree(buf_ptr);
2090 }
2091 lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys);
2092 kfree(buf_ptr1);
2093 } 2081 }
2094 2082
2095 if (elsiocb->context3) { 2083 if (elsiocb->context3) {
2096 buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3; 2084 buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3;
2097 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); 2085 lpfc_els_free_bpl(phba, buf_ptr);
2098 kfree(buf_ptr);
2099 } 2086 }
2100 lpfc_sli_release_iocbq(phba, elsiocb); 2087 lpfc_sli_release_iocbq(phba, elsiocb);
2101 return 0; 2088 return 0;
@@ -2119,15 +2106,15 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2119 "Data: x%x x%x x%x\n", 2106 "Data: x%x x%x x%x\n",
2120 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, 2107 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
2121 ndlp->nlp_rpi); 2108 ndlp->nlp_rpi);
2122 switch (ndlp->nlp_state) { 2109
2123 case NLP_STE_UNUSED_NODE: /* node is just allocated */ 2110 if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
2124 lpfc_drop_node(vport, ndlp); 2111 /* NPort Recovery mode or node is just allocated */
2125 break; 2112 if (!lpfc_nlp_not_used(ndlp)) {
2126 case NLP_STE_NPR_NODE: /* NPort Recovery mode */ 2113 /* If the ndlp is being used by another discovery
2127 lpfc_unreg_rpi(vport, ndlp); 2114 * thread, just unregister the RPI.
2128 break; 2115 */
2129 default: 2116 lpfc_unreg_rpi(vport, ndlp);
2130 break; 2117 }
2131 } 2118 }
2132 lpfc_els_free_iocb(phba, cmdiocb); 2119 lpfc_els_free_iocb(phba, cmdiocb);
2133 return; 2120 return;
@@ -2160,15 +2147,27 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2160 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; 2147 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2161 struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL; 2148 struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
2162 struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL; 2149 struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
2163 IOCB_t *irsp; 2150 IOCB_t *irsp;
2151 uint8_t *pcmd;
2164 LPFC_MBOXQ_t *mbox = NULL; 2152 LPFC_MBOXQ_t *mbox = NULL;
2165 struct lpfc_dmabuf *mp = NULL; 2153 struct lpfc_dmabuf *mp = NULL;
2154 uint32_t ls_rjt = 0;
2166 2155
2167 irsp = &rspiocb->iocb; 2156 irsp = &rspiocb->iocb;
2168 2157
2169 if (cmdiocb->context_un.mbox) 2158 if (cmdiocb->context_un.mbox)
2170 mbox = cmdiocb->context_un.mbox; 2159 mbox = cmdiocb->context_un.mbox;
2171 2160
2161 /* First determine if this is a LS_RJT cmpl */
2162 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
2163 if (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT) {
2164 /* A LS_RJT associated with Default RPI cleanup
2165 * has its own seperate code path.
2166 */
2167 if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
2168 ls_rjt = 1;
2169 }
2170
2172 /* Check to see if link went down during discovery */ 2171 /* Check to see if link went down during discovery */
2173 if (!ndlp || lpfc_els_chk_latt(vport)) { 2172 if (!ndlp || lpfc_els_chk_latt(vport)) {
2174 if (mbox) { 2173 if (mbox) {
@@ -2247,7 +2246,16 @@ out:
2247 spin_lock_irq(shost->host_lock); 2246 spin_lock_irq(shost->host_lock);
2248 ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); 2247 ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
2249 spin_unlock_irq(shost->host_lock); 2248 spin_unlock_irq(shost->host_lock);
2249
2250 /* If the node is not being used by another discovery thread,
2251 * and we are sending a reject, we are done with it.
2252 * Release driver reference count here and free associated
2253 * resources.
2254 */
2255 if (ls_rjt)
2256 lpfc_nlp_not_used(ndlp);
2250 } 2257 }
2258
2251 lpfc_els_free_iocb(phba, cmdiocb); 2259 lpfc_els_free_iocb(phba, cmdiocb);
2252 return; 2260 return;
2253} 2261}
@@ -2418,18 +2426,6 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
2418 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; 2426 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
2419 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); 2427 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
2420 2428
2421 /* If the node is in the UNUSED state, and we are sending
2422 * a reject, we are done with it. Release driver reference
2423 * count here. The outstanding els will release its reference on
2424 * completion, as long as the ndlp stays in the UNUSED list,
2425 * and the node can be freed then.
2426 */
2427 if ((ndlp->nlp_state == NLP_STE_UNUSED_NODE) &&
2428 !(ndlp->nlp_flag & NLP_DELAYED_RM)) {
2429 ndlp->nlp_flag |= NLP_DELAYED_RM;
2430 lpfc_nlp_put(ndlp);
2431 }
2432
2433 if (rc == IOCB_ERROR) { 2429 if (rc == IOCB_ERROR) {
2434 lpfc_els_free_iocb(phba, elsiocb); 2430 lpfc_els_free_iocb(phba, elsiocb);
2435 return 1; 2431 return 1;
@@ -2715,7 +2711,10 @@ lpfc_els_disc_plogi(struct lpfc_vport *vport)
2715 } 2711 }
2716 } 2712 }
2717 } 2713 }
2718 if (sentplogi == 0) { 2714 if (sentplogi) {
2715 lpfc_set_disctmo(vport);
2716 }
2717 else {
2719 spin_lock_irq(shost->host_lock); 2718 spin_lock_irq(shost->host_lock);
2720 vport->fc_flag &= ~FC_NLP_MORE; 2719 vport->fc_flag &= ~FC_NLP_MORE;
2721 spin_unlock_irq(shost->host_lock); 2720 spin_unlock_irq(shost->host_lock);
@@ -3533,6 +3532,7 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3533 * other NLP_FABRIC logins 3532 * other NLP_FABRIC logins
3534 */ 3533 */
3535 lpfc_drop_node(vport, ndlp); 3534 lpfc_drop_node(vport, ndlp);
3535
3536 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { 3536 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
3537 /* Fail outstanding I/O now since this 3537 /* Fail outstanding I/O now since this
3538 * device is marked for PLOGI 3538 * device is marked for PLOGI
@@ -3781,6 +3781,7 @@ static void
3781lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, 3781lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3782 struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) 3782 struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
3783{ 3783{
3784 struct Scsi_Host *shost;
3784 struct lpfc_nodelist *ndlp; 3785 struct lpfc_nodelist *ndlp;
3785 struct ls_rjt stat; 3786 struct ls_rjt stat;
3786 uint32_t *payload; 3787 uint32_t *payload;
@@ -3826,6 +3827,14 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3826 ndlp->nlp_type |= NLP_FABRIC; 3827 ndlp->nlp_type |= NLP_FABRIC;
3827 } 3828 }
3828 } 3829 }
3830 else {
3831 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
3832 /* This is simular to the new node path */
3833 lpfc_nlp_get(ndlp);
3834 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
3835 newnode = 1;
3836 }
3837 }
3829 3838
3830 phba->fc_stat.elsRcvFrame++; 3839 phba->fc_stat.elsRcvFrame++;
3831 if (elsiocb->context1) 3840 if (elsiocb->context1)
@@ -3853,6 +3862,12 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3853 rjt_err = LSRJT_UNABLE_TPC; 3862 rjt_err = LSRJT_UNABLE_TPC;
3854 break; 3863 break;
3855 } 3864 }
3865
3866 shost = lpfc_shost_from_vport(vport);
3867 spin_lock_irq(shost->host_lock);
3868 ndlp->nlp_flag &= ~NLP_TARGET_REMOVE;
3869 spin_unlock_irq(shost->host_lock);
3870
3856 lpfc_disc_state_machine(vport, ndlp, elsiocb, 3871 lpfc_disc_state_machine(vport, ndlp, elsiocb,
3857 NLP_EVT_RCV_PLOGI); 3872 NLP_EVT_RCV_PLOGI);
3858 3873
@@ -3864,7 +3879,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3864 3879
3865 phba->fc_stat.elsRcvFLOGI++; 3880 phba->fc_stat.elsRcvFLOGI++;
3866 lpfc_els_rcv_flogi(vport, elsiocb, ndlp); 3881 lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
3867 if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) 3882 if (newnode)
3868 lpfc_nlp_put(ndlp); 3883 lpfc_nlp_put(ndlp);
3869 break; 3884 break;
3870 case ELS_CMD_LOGO: 3885 case ELS_CMD_LOGO:
@@ -3894,7 +3909,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3894 case ELS_CMD_RSCN: 3909 case ELS_CMD_RSCN:
3895 phba->fc_stat.elsRcvRSCN++; 3910 phba->fc_stat.elsRcvRSCN++;
3896 lpfc_els_rcv_rscn(vport, elsiocb, ndlp); 3911 lpfc_els_rcv_rscn(vport, elsiocb, ndlp);
3897 if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) 3912 if (newnode)
3898 lpfc_nlp_put(ndlp); 3913 lpfc_nlp_put(ndlp);
3899 break; 3914 break;
3900 case ELS_CMD_ADISC: 3915 case ELS_CMD_ADISC:
@@ -3966,7 +3981,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3966 3981
3967 phba->fc_stat.elsRcvLIRR++; 3982 phba->fc_stat.elsRcvLIRR++;
3968 lpfc_els_rcv_lirr(vport, elsiocb, ndlp); 3983 lpfc_els_rcv_lirr(vport, elsiocb, ndlp);
3969 if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) 3984 if (newnode)
3970 lpfc_nlp_put(ndlp); 3985 lpfc_nlp_put(ndlp);
3971 break; 3986 break;
3972 case ELS_CMD_RPS: 3987 case ELS_CMD_RPS:
@@ -3976,7 +3991,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3976 3991
3977 phba->fc_stat.elsRcvRPS++; 3992 phba->fc_stat.elsRcvRPS++;
3978 lpfc_els_rcv_rps(vport, elsiocb, ndlp); 3993 lpfc_els_rcv_rps(vport, elsiocb, ndlp);
3979 if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) 3994 if (newnode)
3980 lpfc_nlp_put(ndlp); 3995 lpfc_nlp_put(ndlp);
3981 break; 3996 break;
3982 case ELS_CMD_RPL: 3997 case ELS_CMD_RPL:
@@ -3986,7 +4001,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3986 4001
3987 phba->fc_stat.elsRcvRPL++; 4002 phba->fc_stat.elsRcvRPL++;
3988 lpfc_els_rcv_rpl(vport, elsiocb, ndlp); 4003 lpfc_els_rcv_rpl(vport, elsiocb, ndlp);
3989 if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) 4004 if (newnode)
3990 lpfc_nlp_put(ndlp); 4005 lpfc_nlp_put(ndlp);
3991 break; 4006 break;
3992 case ELS_CMD_RNID: 4007 case ELS_CMD_RNID:
@@ -3996,7 +4011,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
3996 4011
3997 phba->fc_stat.elsRcvRNID++; 4012 phba->fc_stat.elsRcvRNID++;
3998 lpfc_els_rcv_rnid(vport, elsiocb, ndlp); 4013 lpfc_els_rcv_rnid(vport, elsiocb, ndlp);
3999 if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) 4014 if (newnode)
4000 lpfc_nlp_put(ndlp); 4015 lpfc_nlp_put(ndlp);
4001 break; 4016 break;
4002 default: 4017 default:
@@ -4011,7 +4026,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
4011 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 4026 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
4012 "0115 Unknown ELS command x%x " 4027 "0115 Unknown ELS command x%x "
4013 "received from NPORT x%x\n", cmd, did); 4028 "received from NPORT x%x\n", cmd, did);
4014 if (newnode && (!(ndlp->nlp_flag & NLP_DELAYED_RM))) 4029 if (newnode)
4015 lpfc_nlp_put(ndlp); 4030 lpfc_nlp_put(ndlp);
4016 break; 4031 break;
4017 } 4032 }
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index e181a98caf16..f64ce88e8a06 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -157,6 +157,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
157 struct lpfc_vport *vport; 157 struct lpfc_vport *vport;
158 struct lpfc_hba *phba; 158 struct lpfc_hba *phba;
159 uint8_t *name; 159 uint8_t *name;
160 int put_node;
161 int put_rport;
160 int warn_on = 0; 162 int warn_on = 0;
161 163
162 rport = ndlp->rport; 164 rport = ndlp->rport;
@@ -178,9 +180,6 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
178 return; 180 return;
179 181
180 if (ndlp->nlp_type & NLP_FABRIC) { 182 if (ndlp->nlp_type & NLP_FABRIC) {
181 int put_node;
182 int put_rport;
183
184 /* We will clean up these Nodes in linkup */ 183 /* We will clean up these Nodes in linkup */
185 put_node = rdata->pnode != NULL; 184 put_node = rdata->pnode != NULL;
186 put_rport = ndlp->rport != NULL; 185 put_rport = ndlp->rport != NULL;
@@ -222,23 +221,20 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
222 ndlp->nlp_state, ndlp->nlp_rpi); 221 ndlp->nlp_state, ndlp->nlp_rpi);
223 } 222 }
224 223
224 put_node = rdata->pnode != NULL;
225 put_rport = ndlp->rport != NULL;
226 rdata->pnode = NULL;
227 ndlp->rport = NULL;
228 if (put_node)
229 lpfc_nlp_put(ndlp);
230 if (put_rport)
231 put_device(&rport->dev);
232
225 if (!(vport->load_flag & FC_UNLOADING) && 233 if (!(vport->load_flag & FC_UNLOADING) &&
226 !(ndlp->nlp_flag & NLP_DELAY_TMO) && 234 !(ndlp->nlp_flag & NLP_DELAY_TMO) &&
227 !(ndlp->nlp_flag & NLP_NPR_2B_DISC) && 235 !(ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
228 (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) 236 (ndlp->nlp_state != NLP_STE_UNMAPPED_NODE)) {
229 lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM); 237 lpfc_disc_state_machine(vport, ndlp, NULL, NLP_EVT_DEVICE_RM);
230 else {
231 int put_node;
232 int put_rport;
233
234 put_node = rdata->pnode != NULL;
235 put_rport = ndlp->rport != NULL;
236 rdata->pnode = NULL;
237 ndlp->rport = NULL;
238 if (put_node)
239 lpfc_nlp_put(ndlp);
240 if (put_rport)
241 put_device(&rport->dev);
242 } 238 }
243} 239}
244 240
@@ -546,11 +542,9 @@ lpfc_cleanup_rpis(struct lpfc_vport *vport, int remove)
546 } 542 }
547} 543}
548 544
549static void 545void
550lpfc_port_link_failure(struct lpfc_vport *vport) 546lpfc_port_link_failure(struct lpfc_vport *vport)
551{ 547{
552 struct lpfc_nodelist *ndlp, *next_ndlp;
553
554 /* Cleanup any outstanding RSCN activity */ 548 /* Cleanup any outstanding RSCN activity */
555 lpfc_els_flush_rscn(vport); 549 lpfc_els_flush_rscn(vport);
556 550
@@ -559,11 +553,6 @@ lpfc_port_link_failure(struct lpfc_vport *vport)
559 553
560 lpfc_cleanup_rpis(vport, 0); 554 lpfc_cleanup_rpis(vport, 0);
561 555
562 /* free any ndlp's on unused list */
563 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp)
564 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
565 lpfc_drop_node(vport, ndlp);
566
567 /* Turn off discovery timer if its running */ 556 /* Turn off discovery timer if its running */
568 lpfc_can_disctmo(vport); 557 lpfc_can_disctmo(vport);
569} 558}
@@ -670,7 +659,6 @@ static void
670lpfc_linkup_port(struct lpfc_vport *vport) 659lpfc_linkup_port(struct lpfc_vport *vport)
671{ 660{
672 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 661 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
673 struct lpfc_nodelist *ndlp, *next_ndlp;
674 struct lpfc_hba *phba = vport->phba; 662 struct lpfc_hba *phba = vport->phba;
675 663
676 if ((vport->load_flag & FC_UNLOADING) != 0) 664 if ((vport->load_flag & FC_UNLOADING) != 0)
@@ -697,11 +685,6 @@ lpfc_linkup_port(struct lpfc_vport *vport)
697 if (vport->fc_flag & FC_LBIT) 685 if (vport->fc_flag & FC_LBIT)
698 lpfc_linkup_cleanup_nodes(vport); 686 lpfc_linkup_cleanup_nodes(vport);
699 687
700 /* free any ndlp's in unused state */
701 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
702 nlp_listp)
703 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
704 lpfc_drop_node(vport, ndlp);
705} 688}
706 689
707static int 690static int
@@ -1345,7 +1328,9 @@ out:
1345 lpfc_mbuf_free(phba, mp->virt, mp->phys); 1328 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1346 kfree(mp); 1329 kfree(mp);
1347 mempool_free(pmb, phba->mbox_mem_pool); 1330 mempool_free(pmb, phba->mbox_mem_pool);
1348 lpfc_drop_node(vport, ndlp); 1331
1332 /* If no other thread is using the ndlp, free it */
1333 lpfc_nlp_not_used(ndlp);
1349 1334
1350 if (phba->fc_topology == TOPOLOGY_LOOP) { 1335 if (phba->fc_topology == TOPOLOGY_LOOP) {
1351 /* 1336 /*
@@ -1605,16 +1590,6 @@ lpfc_nlp_set_state(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1605 ndlp->nlp_type &= ~NLP_FC_NODE; 1590 ndlp->nlp_type &= ~NLP_FC_NODE;
1606 } 1591 }
1607 1592
1608 if ((old_state == NLP_STE_UNUSED_NODE) &&
1609 (state != NLP_STE_UNUSED_NODE) &&
1610 (ndlp->nlp_flag & NLP_DELAYED_RM)) {
1611 /* We are using the ndlp after all, so reverse
1612 * the delayed removal of it.
1613 */
1614 ndlp->nlp_flag &= ~NLP_DELAYED_RM;
1615 lpfc_nlp_get(ndlp);
1616 }
1617
1618 if (list_empty(&ndlp->nlp_listp)) { 1593 if (list_empty(&ndlp->nlp_listp)) {
1619 spin_lock_irq(shost->host_lock); 1594 spin_lock_irq(shost->host_lock);
1620 list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes); 1595 list_add_tail(&ndlp->nlp_listp, &vport->fc_nodes);
@@ -1646,9 +1621,16 @@ lpfc_dequeue_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1646void 1621void
1647lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) 1622lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1648{ 1623{
1624 /*
1625 * Use of lpfc_drop_node and UNUSED list. lpfc_drop_node should
1626 * be used if we wish to issue the "last" lpfc_nlp_put() to remove
1627 * the ndlp from the vport. The ndlp resides on the UNUSED list
1628 * until ALL other outstanding threads have completed. Thus, if a
1629 * ndlp is on the UNUSED list already, we should never do another
1630 * lpfc_drop_node() on it.
1631 */
1649 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); 1632 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
1650 if (!(ndlp->nlp_flag & NLP_DELAYED_RM)) 1633 lpfc_nlp_put(ndlp);
1651 lpfc_nlp_put(ndlp);
1652 return; 1634 return;
1653} 1635}
1654 1636
@@ -2116,6 +2098,12 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
2116 } 2098 }
2117 if (vport->fc_flag & FC_RSCN_MODE) { 2099 if (vport->fc_flag & FC_RSCN_MODE) {
2118 if (lpfc_rscn_payload_check(vport, did)) { 2100 if (lpfc_rscn_payload_check(vport, did)) {
2101 /* If we've already recieved a PLOGI from this NPort
2102 * we don't need to try to discover it again.
2103 */
2104 if (ndlp->nlp_flag & NLP_RCV_PLOGI)
2105 return NULL;
2106
2119 spin_lock_irq(shost->host_lock); 2107 spin_lock_irq(shost->host_lock);
2120 ndlp->nlp_flag |= NLP_NPR_2B_DISC; 2108 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2121 spin_unlock_irq(shost->host_lock); 2109 spin_unlock_irq(shost->host_lock);
@@ -2128,8 +2116,13 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
2128 } else 2116 } else
2129 ndlp = NULL; 2117 ndlp = NULL;
2130 } else { 2118 } else {
2119 /* If we've already recieved a PLOGI from this NPort,
2120 * or we are already in the process of discovery on it,
2121 * we don't need to try to discover it again.
2122 */
2131 if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE || 2123 if (ndlp->nlp_state == NLP_STE_ADISC_ISSUE ||
2132 ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) 2124 ndlp->nlp_state == NLP_STE_PLOGI_ISSUE ||
2125 ndlp->nlp_flag & NLP_RCV_PLOGI)
2133 return NULL; 2126 return NULL;
2134 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 2127 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2135 spin_lock_irq(shost->host_lock); 2128 spin_lock_irq(shost->host_lock);
@@ -2497,6 +2490,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
2497 if (ndlp->nlp_type & NLP_FABRIC) { 2490 if (ndlp->nlp_type & NLP_FABRIC) {
2498 /* Clean up the ndlp on Fabric connections */ 2491 /* Clean up the ndlp on Fabric connections */
2499 lpfc_drop_node(vport, ndlp); 2492 lpfc_drop_node(vport, ndlp);
2493
2500 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { 2494 } else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) {
2501 /* Fail outstanding IO now since device 2495 /* Fail outstanding IO now since device
2502 * is marked for PLOGI. 2496 * is marked for PLOGI.
@@ -2515,7 +2509,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
2515 /* Initial FLOGI timeout */ 2509 /* Initial FLOGI timeout */
2516 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, 2510 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
2517 "0222 Initial %s timeout\n", 2511 "0222 Initial %s timeout\n",
2518 vport->vpi ? "FLOGI" : "FDISC"); 2512 vport->vpi ? "FDISC" : "FLOGI");
2519 2513
2520 /* Assume no Fabric and go on with discovery. 2514 /* Assume no Fabric and go on with discovery.
2521 * Check for outstanding ELS FLOGI to abort. 2515 * Check for outstanding ELS FLOGI to abort.
@@ -2537,10 +2531,10 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
2537 /* Next look for NameServer ndlp */ 2531 /* Next look for NameServer ndlp */
2538 ndlp = lpfc_findnode_did(vport, NameServer_DID); 2532 ndlp = lpfc_findnode_did(vport, NameServer_DID);
2539 if (ndlp) 2533 if (ndlp)
2540 lpfc_nlp_put(ndlp); 2534 lpfc_els_abort(phba, ndlp);
2541 /* Start discovery */ 2535
2542 lpfc_disc_start(vport); 2536 /* ReStart discovery */
2543 break; 2537 goto restart_disc;
2544 2538
2545 case LPFC_NS_QRY: 2539 case LPFC_NS_QRY:
2546 /* Check for wait for NameServer Rsp timeout */ 2540 /* Check for wait for NameServer Rsp timeout */
@@ -2559,6 +2553,7 @@ lpfc_disc_timeout_handler(struct lpfc_vport *vport)
2559 } 2553 }
2560 vport->fc_ns_retry = 0; 2554 vport->fc_ns_retry = 0;
2561 2555
2556restart_disc:
2562 /* 2557 /*
2563 * Discovery is over. 2558 * Discovery is over.
2564 * set port_state to PORT_READY if SLI2. 2559 * set port_state to PORT_READY if SLI2.
@@ -2731,8 +2726,7 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
2731 struct lpfc_nodelist *ndlp; 2726 struct lpfc_nodelist *ndlp;
2732 2727
2733 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { 2728 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
2734 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE && 2729 if (filter(ndlp, param))
2735 filter(ndlp, param))
2736 return ndlp; 2730 return ndlp;
2737 } 2731 }
2738 return NULL; 2732 return NULL;
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 729694d97597..ceb185fa3216 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -1334,15 +1334,35 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit)
1334 kfree(HashWorking); 1334 kfree(HashWorking);
1335} 1335}
1336 1336
1337static void 1337void
1338lpfc_cleanup(struct lpfc_vport *vport) 1338lpfc_cleanup(struct lpfc_vport *vport)
1339{ 1339{
1340 struct lpfc_hba *phba = vport->phba;
1340 struct lpfc_nodelist *ndlp, *next_ndlp; 1341 struct lpfc_nodelist *ndlp, *next_ndlp;
1341 1342
1342 /* clean up phba - lpfc specific */ 1343 if (phba->link_state > LPFC_LINK_DOWN)
1343 lpfc_can_disctmo(vport); 1344 lpfc_port_link_failure(vport);
1344 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) 1345
1345 lpfc_nlp_put(ndlp); 1346 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
1347 if (ndlp->nlp_type & NLP_FABRIC)
1348 lpfc_disc_state_machine(vport, ndlp, NULL,
1349 NLP_EVT_DEVICE_RECOVERY);
1350 lpfc_disc_state_machine(vport, ndlp, NULL,
1351 NLP_EVT_DEVICE_RM);
1352 }
1353
1354 /* At this point, ALL ndlp's should be gone */
1355 while (!list_empty(&vport->fc_nodes)) {
1356
1357 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes,
1358 nlp_listp) {
1359 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
1360 "0233 Nodelist x%x not free: %d\n",
1361 ndlp->nlp_DID,
1362 atomic_read(&ndlp->kref.refcount));
1363 lpfc_drop_node(vport, ndlp);
1364 }
1365 }
1346 return; 1366 return;
1347} 1367}
1348 1368
@@ -1463,6 +1483,8 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1463{ 1483{
1464 struct lpfc_vport *vport = phba->pport; 1484 struct lpfc_vport *vport = phba->pport;
1465 struct lpfc_nodelist *ndlp, *next_ndlp; 1485 struct lpfc_nodelist *ndlp, *next_ndlp;
1486 struct lpfc_vport **vports;
1487 int i;
1466 1488
1467 if (vport->fc_flag & FC_OFFLINE_MODE) 1489 if (vport->fc_flag & FC_OFFLINE_MODE)
1468 return; 1490 return;
@@ -1471,10 +1493,32 @@ lpfc_offline_prep(struct lpfc_hba * phba)
1471 1493
1472 lpfc_linkdown(phba); 1494 lpfc_linkdown(phba);
1473 1495
1474 /* Issue an unreg_login to all nodes */ 1496 /* Issue an unreg_login to all nodes on all vports */
1475 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) 1497 vports = lpfc_create_vport_work_array(phba);
1476 if (ndlp->nlp_state != NLP_STE_UNUSED_NODE) 1498 if (vports != NULL) {
1477 lpfc_unreg_rpi(vport, ndlp); 1499 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1500 struct Scsi_Host *shost;
1501
1502 shost = lpfc_shost_from_vport(vports[i]);
1503 list_for_each_entry_safe(ndlp, next_ndlp,
1504 &vports[i]->fc_nodes,
1505 nlp_listp) {
1506 if (ndlp->nlp_state == NLP_STE_UNUSED_NODE)
1507 continue;
1508 if (ndlp->nlp_type & NLP_FABRIC) {
1509 lpfc_disc_state_machine(vports[i], ndlp,
1510 NULL, NLP_EVT_DEVICE_RECOVERY);
1511 lpfc_disc_state_machine(vports[i], ndlp,
1512 NULL, NLP_EVT_DEVICE_RM);
1513 }
1514 spin_lock_irq(shost->host_lock);
1515 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1516 spin_unlock_irq(shost->host_lock);
1517 lpfc_unreg_rpi(vports[i], ndlp);
1518 }
1519 }
1520 }
1521 lpfc_destroy_vport_work_array(vports);
1478 1522
1479 lpfc_sli_flush_mbox_queue(phba); 1523 lpfc_sli_flush_mbox_queue(phba);
1480} 1524}
@@ -1508,7 +1552,6 @@ lpfc_offline(struct lpfc_hba *phba)
1508 if (vports != NULL) 1552 if (vports != NULL)
1509 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) { 1553 for(i = 0; i < LPFC_MAX_VPORTS && vports[i] != NULL; i++) {
1510 shost = lpfc_shost_from_vport(vports[i]); 1554 shost = lpfc_shost_from_vport(vports[i]);
1511 lpfc_cleanup(vports[i]);
1512 spin_lock_irq(shost->host_lock); 1555 spin_lock_irq(shost->host_lock);
1513 vports[i]->work_port_events = 0; 1556 vports[i]->work_port_events = 0;
1514 vports[i]->fc_flag |= FC_OFFLINE_MODE; 1557 vports[i]->fc_flag |= FC_OFFLINE_MODE;
@@ -2061,6 +2104,8 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
2061 2104
2062 fc_remove_host(shost); 2105 fc_remove_host(shost);
2063 scsi_remove_host(shost); 2106 scsi_remove_host(shost);
2107 lpfc_cleanup(vport);
2108
2064 /* 2109 /*
2065 * Bring down the SLI Layer. This step disable all interrupts, 2110 * Bring down the SLI Layer. This step disable all interrupts,
2066 * clears the rings, discards all mailbox commands, and resets 2111 * clears the rings, discards all mailbox commands, and resets
@@ -2075,7 +2120,6 @@ lpfc_pci_remove_one(struct pci_dev *pdev)
2075 spin_unlock_irq(&phba->hbalock); 2120 spin_unlock_irq(&phba->hbalock);
2076 2121
2077 lpfc_debugfs_terminate(vport); 2122 lpfc_debugfs_terminate(vport);
2078 lpfc_cleanup(vport);
2079 2123
2080 kthread_stop(phba->worker_thread); 2124 kthread_stop(phba->worker_thread);
2081 2125
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index 1a16ee9b2e87..bba1fb6103f6 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -406,6 +406,41 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
406 ndlp, mbox); 406 ndlp, mbox);
407 return 1; 407 return 1;
408 } 408 }
409
410 /* If the remote NPort logs into us, before we can initiate
411 * discovery to them, cleanup the NPort from discovery accordingly.
412 */
413 if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
414 spin_lock_irq(shost->host_lock);
415 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
416 spin_unlock_irq(shost->host_lock);
417 del_timer_sync(&ndlp->nlp_delayfunc);
418 ndlp->nlp_last_elscmd = 0;
419
420 if (!list_empty(&ndlp->els_retry_evt.evt_listp))
421 list_del_init(&ndlp->els_retry_evt.evt_listp);
422
423 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
424 spin_lock_irq(shost->host_lock);
425 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
426 spin_unlock_irq(shost->host_lock);
427 if (vport->num_disc_nodes) {
428 /* Check to see if there are more
429 * PLOGIs to be sent
430 */
431 lpfc_more_plogi(vport);
432
433 if (vport->num_disc_nodes == 0) {
434 spin_lock_irq(shost->host_lock);
435 vport->fc_flag &= ~FC_NDISC_ACTIVE;
436 spin_unlock_irq(shost->host_lock);
437 lpfc_can_disctmo(vport);
438 lpfc_end_rscn(vport);
439 }
440 }
441 }
442 }
443
409 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox); 444 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox);
410 return 1; 445 return 1;
411 446
@@ -500,12 +535,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
500 spin_unlock_irq(shost->host_lock); 535 spin_unlock_irq(shost->host_lock);
501 536
502 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; 537 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
503 ndlp->nlp_prev_state = ndlp->nlp_state;
504 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
505 } else {
506 ndlp->nlp_prev_state = ndlp->nlp_state;
507 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
508 } 538 }
539 ndlp->nlp_prev_state = ndlp->nlp_state;
540 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
509 541
510 spin_lock_irq(shost->host_lock); 542 spin_lock_irq(shost->host_lock);
511 ndlp->nlp_flag &= ~NLP_NPR_ADISC; 543 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
@@ -593,6 +625,25 @@ lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
593 return ndlp->nlp_state; 625 return ndlp->nlp_state;
594} 626}
595 627
628static uint32_t
629lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
630 void *arg, uint32_t evt)
631{
632 /* This transition is only legal if we previously
633 * rcv'ed a PLOGI. Since we don't want 2 discovery threads
634 * working on the same NPortID, do nothing for this thread
635 * to stop it.
636 */
637 if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) {
638 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
639 "0253 Illegal State Transition: node x%x "
640 "event x%x, state x%x Data: x%x x%x\n",
641 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
642 ndlp->nlp_flag);
643 }
644 return ndlp->nlp_state;
645}
646
596/* Start of Discovery State Machine routines */ 647/* Start of Discovery State Machine routines */
597 648
598static uint32_t 649static uint32_t
@@ -604,11 +655,8 @@ lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
604 cmdiocb = (struct lpfc_iocbq *) arg; 655 cmdiocb = (struct lpfc_iocbq *) arg;
605 656
606 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { 657 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
607 ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
608 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
609 return ndlp->nlp_state; 658 return ndlp->nlp_state;
610 } 659 }
611 lpfc_drop_node(vport, ndlp);
612 return NLP_STE_FREED_NODE; 660 return NLP_STE_FREED_NODE;
613} 661}
614 662
@@ -617,7 +665,6 @@ lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
617 void *arg, uint32_t evt) 665 void *arg, uint32_t evt)
618{ 666{
619 lpfc_issue_els_logo(vport, ndlp, 0); 667 lpfc_issue_els_logo(vport, ndlp, 0);
620 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
621 return ndlp->nlp_state; 668 return ndlp->nlp_state;
622} 669}
623 670
@@ -632,7 +679,6 @@ lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
632 ndlp->nlp_flag |= NLP_LOGO_ACC; 679 ndlp->nlp_flag |= NLP_LOGO_ACC;
633 spin_unlock_irq(shost->host_lock); 680 spin_unlock_irq(shost->host_lock);
634 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 681 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
635 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE);
636 682
637 return ndlp->nlp_state; 683 return ndlp->nlp_state;
638} 684}
@@ -641,7 +687,6 @@ static uint32_t
641lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 687lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
642 void *arg, uint32_t evt) 688 void *arg, uint32_t evt)
643{ 689{
644 lpfc_drop_node(vport, ndlp);
645 return NLP_STE_FREED_NODE; 690 return NLP_STE_FREED_NODE;
646} 691}
647 692
@@ -649,7 +694,6 @@ static uint32_t
649lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 694lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
650 void *arg, uint32_t evt) 695 void *arg, uint32_t evt)
651{ 696{
652 lpfc_drop_node(vport, ndlp);
653 return NLP_STE_FREED_NODE; 697 return NLP_STE_FREED_NODE;
654} 698}
655 699
@@ -864,7 +908,7 @@ out:
864 908
865 /* Free this node since the driver cannot login or has the wrong 909 /* Free this node since the driver cannot login or has the wrong
866 sparm */ 910 sparm */
867 lpfc_drop_node(vport, ndlp); 911 lpfc_nlp_not_used(ndlp);
868 return NLP_STE_FREED_NODE; 912 return NLP_STE_FREED_NODE;
869} 913}
870 914
@@ -1195,8 +1239,8 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
1195 * retry discovery. 1239 * retry discovery.
1196 */ 1240 */
1197 if (mb->mbxStatus == MBXERR_RPI_FULL) { 1241 if (mb->mbxStatus == MBXERR_RPI_FULL) {
1198 ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; 1242 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1199 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); 1243 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1200 return ndlp->nlp_state; 1244 return ndlp->nlp_state;
1201 } 1245 }
1202 1246
@@ -1376,7 +1420,7 @@ out:
1376 lpfc_issue_els_logo(vport, ndlp, 0); 1420 lpfc_issue_els_logo(vport, ndlp, 0);
1377 1421
1378 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; 1422 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
1379 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); 1423 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1380 return ndlp->nlp_state; 1424 return ndlp->nlp_state;
1381 } 1425 }
1382 1426
@@ -1751,7 +1795,7 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1751 1795
1752 irsp = &rspiocb->iocb; 1796 irsp = &rspiocb->iocb;
1753 if (irsp->ulpStatus) { 1797 if (irsp->ulpStatus) {
1754 lpfc_drop_node(vport, ndlp); 1798 lpfc_nlp_not_used(ndlp);
1755 return NLP_STE_FREED_NODE; 1799 return NLP_STE_FREED_NODE;
1756 } 1800 }
1757 return ndlp->nlp_state; 1801 return ndlp->nlp_state;
@@ -1966,7 +2010,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
1966 lpfc_rcv_padisc_reglogin_issue, /* RCV_ADISC */ 2010 lpfc_rcv_padisc_reglogin_issue, /* RCV_ADISC */
1967 lpfc_rcv_padisc_reglogin_issue, /* RCV_PDISC */ 2011 lpfc_rcv_padisc_reglogin_issue, /* RCV_PDISC */
1968 lpfc_rcv_prlo_reglogin_issue, /* RCV_PRLO */ 2012 lpfc_rcv_prlo_reglogin_issue, /* RCV_PRLO */
1969 lpfc_disc_illegal, /* CMPL_PLOGI */ 2013 lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */
1970 lpfc_disc_illegal, /* CMPL_PRLI */ 2014 lpfc_disc_illegal, /* CMPL_PRLI */
1971 lpfc_disc_illegal, /* CMPL_LOGO */ 2015 lpfc_disc_illegal, /* CMPL_LOGO */
1972 lpfc_disc_illegal, /* CMPL_ADISC */ 2016 lpfc_disc_illegal, /* CMPL_ADISC */
@@ -1980,7 +2024,7 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
1980 lpfc_rcv_padisc_prli_issue, /* RCV_ADISC */ 2024 lpfc_rcv_padisc_prli_issue, /* RCV_ADISC */
1981 lpfc_rcv_padisc_prli_issue, /* RCV_PDISC */ 2025 lpfc_rcv_padisc_prli_issue, /* RCV_PDISC */
1982 lpfc_rcv_prlo_prli_issue, /* RCV_PRLO */ 2026 lpfc_rcv_prlo_prli_issue, /* RCV_PRLO */
1983 lpfc_disc_illegal, /* CMPL_PLOGI */ 2027 lpfc_cmpl_plogi_illegal, /* CMPL_PLOGI */
1984 lpfc_cmpl_prli_prli_issue, /* CMPL_PRLI */ 2028 lpfc_cmpl_prli_prli_issue, /* CMPL_PRLI */
1985 lpfc_disc_illegal, /* CMPL_LOGO */ 2029 lpfc_disc_illegal, /* CMPL_LOGO */
1986 lpfc_disc_illegal, /* CMPL_ADISC */ 2030 lpfc_disc_illegal, /* CMPL_ADISC */
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index fd07d9d7f507..378c01200b02 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -445,7 +445,6 @@ int
445lpfc_vport_delete(struct fc_vport *fc_vport) 445lpfc_vport_delete(struct fc_vport *fc_vport)
446{ 446{
447 struct lpfc_nodelist *ndlp = NULL; 447 struct lpfc_nodelist *ndlp = NULL;
448 struct lpfc_nodelist *next_ndlp;
449 struct Scsi_Host *shost = (struct Scsi_Host *) fc_vport->shost; 448 struct Scsi_Host *shost = (struct Scsi_Host *) fc_vport->shost;
450 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data; 449 struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
451 struct lpfc_hba *phba = vport->phba; 450 struct lpfc_hba *phba = vport->phba;
@@ -531,23 +530,20 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
531 } 530 }
532 531
533skip_logo: 532skip_logo:
533 lpfc_cleanup(vport);
534 lpfc_sli_host_down(vport); 534 lpfc_sli_host_down(vport);
535 535
536 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
537 lpfc_disc_state_machine(vport, ndlp, NULL,
538 NLP_EVT_DEVICE_RECOVERY);
539 lpfc_disc_state_machine(vport, ndlp, NULL,
540 NLP_EVT_DEVICE_RM);
541 }
542
543 lpfc_stop_vport_timers(vport); 536 lpfc_stop_vport_timers(vport);
544 lpfc_unreg_all_rpis(vport); 537 lpfc_unreg_all_rpis(vport);
545 lpfc_unreg_default_rpis(vport); 538
546 /* 539 if (!(phba->pport->load_flag & FC_UNLOADING)) {
547 * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi) does the 540 lpfc_unreg_default_rpis(vport);
548 * scsi_host_put() to release the vport. 541 /*
549 */ 542 * Completion of unreg_vpi (lpfc_mbx_cmpl_unreg_vpi)
550 lpfc_mbx_unreg_vpi(vport); 543 * does the scsi_host_put() to release the vport.
544 */
545 lpfc_mbx_unreg_vpi(vport);
546 }
551 547
552 lpfc_free_vpi(phba, vport->vpi); 548 lpfc_free_vpi(phba, vport->vpi);
553 vport->work_port_events = 0; 549 vport->work_port_events = 0;