diff options
author | Jamie Wellnitz <Jamie.Wellnitz@emulex.com> | 2006-02-28 19:25:28 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-02-28 20:01:51 -0500 |
commit | 5024ab179c13d763f95c8391f45f22309609f479 (patch) | |
tree | 7c22b094371c8831f8724d7a2e8580a3ed394c1f | |
parent | 41415862a23f422b80eccc92cf885935139e2415 (diff) |
[SCSI] lpfc 8.1.2: Added support for FAN
Added support for FAN
Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/lpfc/lpfc_disc.h | 1 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 123 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 13 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 61 |
4 files changed, 140 insertions, 58 deletions
diff --git a/drivers/scsi/lpfc/lpfc_disc.h b/drivers/scsi/lpfc/lpfc_disc.h index 4dfcd4eda2fc..8932b1be2b60 100644 --- a/drivers/scsi/lpfc/lpfc_disc.h +++ b/drivers/scsi/lpfc/lpfc_disc.h | |||
@@ -62,6 +62,7 @@ struct lpfc_nodelist { | |||
62 | 62 | ||
63 | uint16_t nlp_rpi; | 63 | uint16_t nlp_rpi; |
64 | uint16_t nlp_state; /* state transition indicator */ | 64 | uint16_t nlp_state; /* state transition indicator */ |
65 | uint16_t nlp_prev_state; /* state transition indicator */ | ||
65 | uint16_t nlp_xri; /* output exchange id for RPI */ | 66 | uint16_t nlp_xri; /* output exchange id for RPI */ |
66 | uint16_t nlp_sid; /* scsi id */ | 67 | uint16_t nlp_sid; /* scsi id */ |
67 | #define NLP_NO_SID 0xffff | 68 | #define NLP_NO_SID 0xffff |
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 70581b9eafaf..a88a1477b552 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -1201,12 +1201,10 @@ lpfc_cmpl_els_logo(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1201 | NLP_EVT_CMPL_LOGO); | 1201 | NLP_EVT_CMPL_LOGO); |
1202 | } | 1202 | } |
1203 | } else { | 1203 | } else { |
1204 | /* Good status, call state machine */ | 1204 | /* Good status, call state machine. |
1205 | * This will unregister the rpi if needed. | ||
1206 | */ | ||
1205 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); | 1207 | lpfc_disc_state_machine(phba, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); |
1206 | |||
1207 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | ||
1208 | lpfc_unreg_rpi(phba, ndlp); | ||
1209 | } | ||
1210 | } | 1208 | } |
1211 | 1209 | ||
1212 | out: | 1210 | out: |
@@ -1435,8 +1433,9 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1435 | 1433 | ||
1436 | phba = ndlp->nlp_phba; | 1434 | phba = ndlp->nlp_phba; |
1437 | spin_lock_irq(phba->host->host_lock); | 1435 | spin_lock_irq(phba->host->host_lock); |
1438 | did = (uint32_t) (ndlp->nlp_DID); | 1436 | did = ndlp->nlp_DID; |
1439 | cmd = (uint32_t) (ndlp->nlp_last_elscmd); | 1437 | cmd = ndlp->nlp_last_elscmd; |
1438 | ndlp->nlp_last_elscmd = 0; | ||
1440 | 1439 | ||
1441 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1440 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1442 | spin_unlock_irq(phba->host->host_lock); | 1441 | spin_unlock_irq(phba->host->host_lock); |
@@ -1453,24 +1452,28 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) | |||
1453 | break; | 1452 | break; |
1454 | case ELS_CMD_PLOGI: | 1453 | case ELS_CMD_PLOGI: |
1455 | if (!lpfc_issue_els_plogi(phba, ndlp, retry)) { | 1454 | if (!lpfc_issue_els_plogi(phba, ndlp, retry)) { |
1455 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1456 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1456 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1457 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1457 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1458 | } | 1458 | } |
1459 | break; | 1459 | break; |
1460 | case ELS_CMD_ADISC: | 1460 | case ELS_CMD_ADISC: |
1461 | if (!lpfc_issue_els_adisc(phba, ndlp, retry)) { | 1461 | if (!lpfc_issue_els_adisc(phba, ndlp, retry)) { |
1462 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1462 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1463 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1463 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1464 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1464 | } | 1465 | } |
1465 | break; | 1466 | break; |
1466 | case ELS_CMD_PRLI: | 1467 | case ELS_CMD_PRLI: |
1467 | if (!lpfc_issue_els_prli(phba, ndlp, retry)) { | 1468 | if (!lpfc_issue_els_prli(phba, ndlp, retry)) { |
1469 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1468 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; | 1470 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; |
1469 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | 1471 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); |
1470 | } | 1472 | } |
1471 | break; | 1473 | break; |
1472 | case ELS_CMD_LOGO: | 1474 | case ELS_CMD_LOGO: |
1473 | if (!lpfc_issue_els_logo(phba, ndlp, retry)) { | 1475 | if (!lpfc_issue_els_logo(phba, ndlp, retry)) { |
1476 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1474 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1477 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1475 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1478 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1476 | } | 1479 | } |
@@ -1630,6 +1633,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1630 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 1633 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
1631 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1634 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1632 | 1635 | ||
1636 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1633 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1637 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1634 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1638 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1635 | ndlp->nlp_last_elscmd = cmd; | 1639 | ndlp->nlp_last_elscmd = cmd; |
@@ -1641,21 +1645,25 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1641 | lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); | 1645 | lpfc_issue_els_flogi(phba, ndlp, cmdiocb->retry); |
1642 | return 1; | 1646 | return 1; |
1643 | case ELS_CMD_PLOGI: | 1647 | case ELS_CMD_PLOGI: |
1648 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1644 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1649 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1645 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1650 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1646 | lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry); | 1651 | lpfc_issue_els_plogi(phba, ndlp, cmdiocb->retry); |
1647 | return 1; | 1652 | return 1; |
1648 | case ELS_CMD_ADISC: | 1653 | case ELS_CMD_ADISC: |
1654 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1649 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1655 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1650 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1656 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1651 | lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); | 1657 | lpfc_issue_els_adisc(phba, ndlp, cmdiocb->retry); |
1652 | return 1; | 1658 | return 1; |
1653 | case ELS_CMD_PRLI: | 1659 | case ELS_CMD_PRLI: |
1660 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1654 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; | 1661 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; |
1655 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | 1662 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); |
1656 | lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); | 1663 | lpfc_issue_els_prli(phba, ndlp, cmdiocb->retry); |
1657 | return 1; | 1664 | return 1; |
1658 | case ELS_CMD_LOGO: | 1665 | case ELS_CMD_LOGO: |
1666 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1659 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1667 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1660 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1668 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1661 | lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); | 1669 | lpfc_issue_els_logo(phba, ndlp, cmdiocb->retry); |
@@ -1719,10 +1727,6 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1719 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 1727 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, |
1720 | ndlp->nlp_state, ndlp->nlp_rpi); | 1728 | ndlp->nlp_state, ndlp->nlp_rpi); |
1721 | 1729 | ||
1722 | spin_lock_irq(phba->host->host_lock); | ||
1723 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; | ||
1724 | spin_unlock_irq(phba->host->host_lock); | ||
1725 | |||
1726 | switch (ndlp->nlp_state) { | 1730 | switch (ndlp->nlp_state) { |
1727 | case NLP_STE_UNUSED_NODE: /* node is just allocated */ | 1731 | case NLP_STE_UNUSED_NODE: /* node is just allocated */ |
1728 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1732 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
@@ -1776,6 +1780,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1776 | lpfc_unreg_rpi(phba, ndlp); | 1780 | lpfc_unreg_rpi(phba, ndlp); |
1777 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 1781 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
1778 | mbox->context2 = ndlp; | 1782 | mbox->context2 = ndlp; |
1783 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
1779 | ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE; | 1784 | ndlp->nlp_state = NLP_STE_REG_LOGIN_ISSUE; |
1780 | lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); | 1785 | lpfc_nlp_list(phba, ndlp, NLP_REGLOGIN_LIST); |
1781 | if (lpfc_sli_issue_mbox(phba, mbox, | 1786 | if (lpfc_sli_issue_mbox(phba, mbox, |
@@ -1790,6 +1795,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1790 | mempool_free( mbox, phba->mbox_mem_pool); | 1795 | mempool_free( mbox, phba->mbox_mem_pool); |
1791 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 1796 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
1792 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | 1797 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); |
1798 | ndlp = NULL; | ||
1793 | } | 1799 | } |
1794 | } | 1800 | } |
1795 | } | 1801 | } |
@@ -1827,6 +1833,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, | |||
1827 | if ((elsiocb = | 1833 | if ((elsiocb = |
1828 | lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, | 1834 | lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry, |
1829 | ndlp, ELS_CMD_ACC)) == 0) { | 1835 | ndlp, ELS_CMD_ACC)) == 0) { |
1836 | ndlp->nlp_flag &= ~NLP_LOGO_ACC; | ||
1830 | return 1; | 1837 | return 1; |
1831 | } | 1838 | } |
1832 | icmd = &elsiocb->iocb; | 1839 | icmd = &elsiocb->iocb; |
@@ -2172,6 +2179,7 @@ lpfc_els_disc_adisc(struct lpfc_hba * phba) | |||
2172 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 2179 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
2173 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 2180 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
2174 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 2181 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
2182 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2175 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 2183 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
2176 | lpfc_nlp_list(phba, ndlp, | 2184 | lpfc_nlp_list(phba, ndlp, |
2177 | NLP_ADISC_LIST); | 2185 | NLP_ADISC_LIST); |
@@ -2209,6 +2217,7 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) | |||
2209 | if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 2217 | if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && |
2210 | (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { | 2218 | (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { |
2211 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 2219 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { |
2220 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2212 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2221 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2213 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 2222 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
2214 | lpfc_issue_els_plogi(phba, ndlp, 0); | 2223 | lpfc_issue_els_plogi(phba, ndlp, 0); |
@@ -2350,8 +2359,13 @@ lpfc_rscn_recovery_check(struct lpfc_hba * phba) | |||
2350 | 2359 | ||
2351 | lpfc_disc_state_machine(phba, ndlp, NULL, | 2360 | lpfc_disc_state_machine(phba, ndlp, NULL, |
2352 | NLP_EVT_DEVICE_RECOVERY); | 2361 | NLP_EVT_DEVICE_RECOVERY); |
2362 | |||
2363 | /* Make sure NLP_DELAY_TMO is NOT running | ||
2364 | * after a device recovery event. | ||
2365 | */ | ||
2353 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 2366 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
2354 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 2367 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
2368 | ndlp->nlp_last_elscmd = 0; | ||
2355 | del_timer_sync(&ndlp->nlp_delayfunc); | 2369 | del_timer_sync(&ndlp->nlp_delayfunc); |
2356 | if (!list_empty(&ndlp-> | 2370 | if (!list_empty(&ndlp-> |
2357 | els_retry_evt.evt_listp)) | 2371 | els_retry_evt.evt_listp)) |
@@ -2503,6 +2517,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) | |||
2503 | } else { | 2517 | } else { |
2504 | lpfc_nlp_init(phba, ndlp, NameServer_DID); | 2518 | lpfc_nlp_init(phba, ndlp, NameServer_DID); |
2505 | ndlp->nlp_type |= NLP_FABRIC; | 2519 | ndlp->nlp_type |= NLP_FABRIC; |
2520 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2506 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2521 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2507 | lpfc_issue_els_plogi(phba, ndlp, 0); | 2522 | lpfc_issue_els_plogi(phba, ndlp, 0); |
2508 | /* Wait for NameServer login cmpl before we can | 2523 | /* Wait for NameServer login cmpl before we can |
@@ -2930,6 +2945,7 @@ lpfc_els_rcv_farp(struct lpfc_hba * phba, | |||
2930 | (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) { | 2945 | (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) { |
2931 | /* Log back into the node before sending the FARP. */ | 2946 | /* Log back into the node before sending the FARP. */ |
2932 | if (fp->Rflags & FARP_REQUEST_PLOGI) { | 2947 | if (fp->Rflags & FARP_REQUEST_PLOGI) { |
2948 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2933 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 2949 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
2934 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 2950 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
2935 | lpfc_issue_els_plogi(phba, ndlp, 0); | 2951 | lpfc_issue_els_plogi(phba, ndlp, 0); |
@@ -2974,46 +2990,89 @@ lpfc_els_rcv_farpr(struct lpfc_hba * phba, | |||
2974 | 2990 | ||
2975 | static int | 2991 | static int |
2976 | lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 2992 | lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, |
2977 | struct lpfc_nodelist * ndlp) | 2993 | struct lpfc_nodelist * fan_ndlp) |
2978 | { | 2994 | { |
2979 | struct lpfc_dmabuf *pcmd; | 2995 | struct lpfc_dmabuf *pcmd; |
2980 | uint32_t *lp; | 2996 | uint32_t *lp; |
2981 | IOCB_t *icmd; | 2997 | IOCB_t *icmd; |
2982 | FAN *fp; | ||
2983 | uint32_t cmd, did; | 2998 | uint32_t cmd, did; |
2999 | FAN *fp; | ||
3000 | struct lpfc_nodelist *ndlp, *next_ndlp; | ||
3001 | |||
3002 | /* FAN received */ | ||
3003 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, "%d:265 FAN received\n", | ||
3004 | phba->brd_no); | ||
2984 | 3005 | ||
2985 | icmd = &cmdiocb->iocb; | 3006 | icmd = &cmdiocb->iocb; |
2986 | did = icmd->un.elsreq64.remoteID; | 3007 | did = icmd->un.elsreq64.remoteID; |
2987 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 3008 | pcmd = (struct lpfc_dmabuf *)cmdiocb->context2; |
2988 | lp = (uint32_t *) pcmd->virt; | 3009 | lp = (uint32_t *)pcmd->virt; |
2989 | 3010 | ||
2990 | cmd = *lp++; | 3011 | cmd = *lp++; |
2991 | fp = (FAN *) lp; | 3012 | fp = (FAN *)lp; |
2992 | 3013 | ||
2993 | /* FAN received */ | 3014 | /* FAN received; Fan does not have a reply sequence */ |
2994 | |||
2995 | /* ACCEPT the FAN request */ | ||
2996 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | ||
2997 | 3015 | ||
2998 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { | 3016 | if (phba->hba_state == LPFC_LOCAL_CFG_LINK) { |
2999 | /* The discovery state machine needs to take a different | 3017 | if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName, |
3000 | * action if this node has switched fabrics | 3018 | sizeof(struct lpfc_name)) != 0) || |
3001 | */ | 3019 | (memcmp(&phba->fc_fabparam.portName, &fp->FportName, |
3002 | if ((memcmp(&fp->FportName, &phba->fc_fabparam.portName, | 3020 | sizeof(struct lpfc_name)) != 0)) { |
3003 | sizeof (struct lpfc_name)) != 0) | 3021 | /* |
3004 | || | 3022 | * This node has switched fabrics. FLOGI is required |
3005 | (memcmp(&fp->FnodeName, &phba->fc_fabparam.nodeName, | 3023 | * Clean up the old rpi's |
3006 | sizeof (struct lpfc_name)) != 0)) { | ||
3007 | /* This node has switched fabrics. An FLOGI is required | ||
3008 | * after the timeout | ||
3009 | */ | 3024 | */ |
3025 | |||
3026 | list_for_each_entry_safe(ndlp, next_ndlp, | ||
3027 | &phba->fc_npr_list, nlp_listp) { | ||
3028 | |||
3029 | if (ndlp->nlp_type & NLP_FABRIC) { | ||
3030 | /* | ||
3031 | * Clean up old Fabric, Nameserver and | ||
3032 | * other NLP_FABRIC logins | ||
3033 | */ | ||
3034 | lpfc_nlp_list(phba, ndlp, NLP_NO_LIST); | ||
3035 | } | ||
3036 | else if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | ||
3037 | /* Fail outstanding I/O now since this | ||
3038 | * device is marked for PLOGI | ||
3039 | */ | ||
3040 | lpfc_unreg_rpi(phba, ndlp); | ||
3041 | } | ||
3042 | } | ||
3043 | |||
3044 | phba->hba_state = LPFC_FLOGI; | ||
3045 | lpfc_set_disctmo(phba); | ||
3046 | lpfc_initial_flogi(phba); | ||
3010 | return 0; | 3047 | return 0; |
3011 | } | 3048 | } |
3049 | /* Discovery not needed, | ||
3050 | * move the nodes to their original state. | ||
3051 | */ | ||
3052 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | ||
3053 | nlp_listp) { | ||
3012 | 3054 | ||
3013 | /* Start discovery */ | 3055 | switch (ndlp->nlp_prev_state) { |
3056 | case NLP_STE_UNMAPPED_NODE: | ||
3057 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
3058 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | ||
3059 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | ||
3060 | break; | ||
3061 | |||
3062 | case NLP_STE_MAPPED_NODE: | ||
3063 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
3064 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | ||
3065 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | ||
3066 | break; | ||
3067 | |||
3068 | default: | ||
3069 | break; | ||
3070 | } | ||
3071 | } | ||
3072 | |||
3073 | /* Start discovery - this should just do CLEAR_LA */ | ||
3014 | lpfc_disc_start(phba); | 3074 | lpfc_disc_start(phba); |
3015 | } | 3075 | } |
3016 | |||
3017 | return 0; | 3076 | return 0; |
3018 | } | 3077 | } |
3019 | 3078 | ||
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 55454923029d..710efec1221f 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -309,14 +309,12 @@ lpfc_linkdown(struct lpfc_hba * phba) | |||
309 | LPFC_MBOXQ_t *mb; | 309 | LPFC_MBOXQ_t *mb; |
310 | int rc, i; | 310 | int rc, i; |
311 | 311 | ||
312 | if (phba->hba_state == LPFC_LINK_DOWN) { | ||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | psli = &phba->sli; | 312 | psli = &phba->sli; |
317 | |||
318 | /* sysfs or selective reset may call this routine to clean up */ | 313 | /* sysfs or selective reset may call this routine to clean up */ |
319 | if (phba->hba_state > LPFC_LINK_DOWN) { | 314 | if (phba->hba_state >= LPFC_LINK_DOWN) { |
315 | if (phba->hba_state == LPFC_LINK_DOWN) | ||
316 | return 0; | ||
317 | |||
320 | spin_lock_irq(phba->host->host_lock); | 318 | spin_lock_irq(phba->host->host_lock); |
321 | phba->hba_state = LPFC_LINK_DOWN; | 319 | phba->hba_state = LPFC_LINK_DOWN; |
322 | spin_unlock_irq(phba->host->host_lock); | 320 | spin_unlock_irq(phba->host->host_lock); |
@@ -1172,6 +1170,7 @@ lpfc_nlp_list(struct lpfc_hba * phba, struct lpfc_nodelist * nlp, int list) | |||
1172 | spin_lock_irq(phba->host->host_lock); | 1170 | spin_lock_irq(phba->host->host_lock); |
1173 | nlp->nlp_flag &= ~NLP_DELAY_TMO; | 1171 | nlp->nlp_flag &= ~NLP_DELAY_TMO; |
1174 | spin_unlock_irq(phba->host->host_lock); | 1172 | spin_unlock_irq(phba->host->host_lock); |
1173 | nlp->nlp_last_elscmd = 0; | ||
1175 | del_timer_sync(&nlp->nlp_delayfunc); | 1174 | del_timer_sync(&nlp->nlp_delayfunc); |
1176 | if (!list_empty(&nlp->els_retry_evt.evt_listp)) | 1175 | if (!list_empty(&nlp->els_retry_evt.evt_listp)) |
1177 | list_del_init(&nlp->els_retry_evt.evt_listp); | 1176 | list_del_init(&nlp->els_retry_evt.evt_listp); |
@@ -1595,6 +1594,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1595 | spin_unlock_irq(phba->host->host_lock); | 1594 | spin_unlock_irq(phba->host->host_lock); |
1596 | del_timer_sync(&ndlp->nlp_tmofunc); | 1595 | del_timer_sync(&ndlp->nlp_tmofunc); |
1597 | 1596 | ||
1597 | ndlp->nlp_last_elscmd = 0; | ||
1598 | del_timer_sync(&ndlp->nlp_delayfunc); | 1598 | del_timer_sync(&ndlp->nlp_delayfunc); |
1599 | 1599 | ||
1600 | if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp)) | 1600 | if (!list_empty(&ndlp->nodev_timeout_evt.evt_listp)) |
@@ -1630,6 +1630,7 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
1630 | spin_lock_irq(phba->host->host_lock); | 1630 | spin_lock_irq(phba->host->host_lock); |
1631 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 1631 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
1632 | spin_unlock_irq(phba->host->host_lock); | 1632 | spin_unlock_irq(phba->host->host_lock); |
1633 | ndlp->nlp_last_elscmd = 0; | ||
1633 | del_timer_sync(&ndlp->nlp_delayfunc); | 1634 | del_timer_sync(&ndlp->nlp_delayfunc); |
1634 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 1635 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) |
1635 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 1636 | list_del_init(&ndlp->els_retry_evt.evt_listp); |
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index a580e1e50672..4bf232a9adc9 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -262,6 +262,7 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
262 | /* If we are delaying issuing an ELS command, cancel it */ | 262 | /* If we are delaying issuing an ELS command, cancel it */ |
263 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 263 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
264 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; | 264 | ndlp->nlp_flag &= ~NLP_DELAY_TMO; |
265 | ndlp->nlp_last_elscmd = 0; | ||
265 | del_timer_sync(&ndlp->nlp_delayfunc); | 266 | del_timer_sync(&ndlp->nlp_delayfunc); |
266 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 267 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) |
267 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 268 | list_del_init(&ndlp->els_retry_evt.evt_listp); |
@@ -398,16 +399,8 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
398 | */ | 399 | */ |
399 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 400 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
400 | mbox->context2 = ndlp; | 401 | mbox->context2 = ndlp; |
401 | ndlp->nlp_flag |= NLP_ACC_REGLOGIN; | 402 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); |
402 | 403 | ||
403 | /* If there is an outstanding PLOGI issued, abort it before | ||
404 | * sending ACC rsp to PLOGI recieved. | ||
405 | */ | ||
406 | if (ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) { | ||
407 | /* software abort outstanding PLOGI */ | ||
408 | lpfc_els_abort(phba, ndlp, 1); | ||
409 | } | ||
410 | ndlp->nlp_flag |= NLP_RCV_PLOGI; | ||
411 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); | 404 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); |
412 | return 1; | 405 | return 1; |
413 | 406 | ||
@@ -465,13 +458,14 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
465 | stat.un.b.vendorUnique = 0; | 458 | stat.un.b.vendorUnique = 0; |
466 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 459 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); |
467 | 460 | ||
468 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
469 | /* 1 sec timeout */ | 461 | /* 1 sec timeout */ |
470 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 462 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
471 | 463 | ||
472 | spin_lock_irq(phba->host->host_lock); | 464 | spin_lock_irq(phba->host->host_lock); |
473 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 465 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
474 | spin_unlock_irq(phba->host->host_lock); | 466 | spin_unlock_irq(phba->host->host_lock); |
467 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
468 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
475 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 469 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
476 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 470 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
477 | return 0; | 471 | return 0; |
@@ -492,15 +486,17 @@ lpfc_rcv_logo(struct lpfc_hba * phba, | |||
492 | if (!(ndlp->nlp_type & NLP_FABRIC) || | 486 | if (!(ndlp->nlp_type & NLP_FABRIC) || |
493 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | 487 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { |
494 | /* Only try to re-login if this is NOT a Fabric Node */ | 488 | /* Only try to re-login if this is NOT a Fabric Node */ |
495 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
496 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 489 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
497 | spin_lock_irq(phba->host->host_lock); | 490 | spin_lock_irq(phba->host->host_lock); |
498 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 491 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
499 | spin_unlock_irq(phba->host->host_lock); | 492 | spin_unlock_irq(phba->host->host_lock); |
500 | 493 | ||
494 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
495 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
501 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 496 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
502 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 497 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
503 | } else { | 498 | } else { |
499 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
504 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | 500 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; |
505 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 501 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
506 | } | 502 | } |
@@ -595,6 +591,7 @@ lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, | |||
595 | cmdiocb = (struct lpfc_iocbq *) arg; | 591 | cmdiocb = (struct lpfc_iocbq *) arg; |
596 | 592 | ||
597 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 593 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
594 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | ||
598 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; | 595 | ndlp->nlp_state = NLP_STE_UNUSED_NODE; |
599 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); | 596 | lpfc_nlp_list(phba, ndlp, NLP_UNUSED_LIST); |
600 | return ndlp->nlp_state; | 597 | return ndlp->nlp_state; |
@@ -708,10 +705,6 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, | |||
708 | 705 | ||
709 | /* software abort outstanding PLOGI */ | 706 | /* software abort outstanding PLOGI */ |
710 | lpfc_els_abort(phba, ndlp, 1); | 707 | lpfc_els_abort(phba, ndlp, 1); |
711 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | ||
712 | spin_lock_irq(phba->host->host_lock); | ||
713 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
714 | spin_unlock_irq(phba->host->host_lock); | ||
715 | 708 | ||
716 | if (evt == NLP_EVT_RCV_LOGO) { | 709 | if (evt == NLP_EVT_RCV_LOGO) { |
717 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 710 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
@@ -721,7 +714,12 @@ lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, | |||
721 | } | 714 | } |
722 | 715 | ||
723 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 716 | /* Put ndlp in npr list set plogi timer for 1 sec */ |
724 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | 717 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
718 | spin_lock_irq(phba->host->host_lock); | ||
719 | ndlp->nlp_flag |= NLP_DELAY_TMO; | ||
720 | spin_unlock_irq(phba->host->host_lock); | ||
721 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
722 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | ||
725 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 723 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
726 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 724 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
727 | 725 | ||
@@ -744,6 +742,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
744 | rspiocb = cmdiocb->context_un.rsp_iocb; | 742 | rspiocb = cmdiocb->context_un.rsp_iocb; |
745 | 743 | ||
746 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | 744 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
745 | /* Recovery from PLOGI collision logic */ | ||
747 | return ndlp->nlp_state; | 746 | return ndlp->nlp_state; |
748 | } | 747 | } |
749 | 748 | ||
@@ -859,6 +858,7 @@ lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, | |||
859 | /* software abort outstanding PLOGI */ | 858 | /* software abort outstanding PLOGI */ |
860 | lpfc_els_abort(phba, ndlp, 1); | 859 | lpfc_els_abort(phba, ndlp, 1); |
861 | 860 | ||
861 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | ||
862 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 862 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
863 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 863 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
864 | spin_lock_irq(phba->host->host_lock); | 864 | spin_lock_irq(phba->host->host_lock); |
@@ -883,6 +883,7 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, | |||
883 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 883 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { |
884 | return ndlp->nlp_state; | 884 | return ndlp->nlp_state; |
885 | } | 885 | } |
886 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
886 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 887 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
887 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 888 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
888 | lpfc_issue_els_plogi(phba, ndlp, 0); | 889 | lpfc_issue_els_plogi(phba, ndlp, 0); |
@@ -963,25 +964,29 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, | |||
963 | 964 | ||
964 | if ((irsp->ulpStatus) || | 965 | if ((irsp->ulpStatus) || |
965 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { | 966 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { |
966 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
967 | /* 1 sec timeout */ | 967 | /* 1 sec timeout */ |
968 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 968 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
969 | spin_lock_irq(phba->host->host_lock); | 969 | spin_lock_irq(phba->host->host_lock); |
970 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 970 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
971 | spin_unlock_irq(phba->host->host_lock); | 971 | spin_unlock_irq(phba->host->host_lock); |
972 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
972 | 973 | ||
973 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); | 974 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); |
974 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); | 975 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); |
975 | 976 | ||
977 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
976 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 978 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
977 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 979 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
978 | lpfc_unreg_rpi(phba, ndlp); | 980 | lpfc_unreg_rpi(phba, ndlp); |
979 | return ndlp->nlp_state; | 981 | return ndlp->nlp_state; |
980 | } | 982 | } |
983 | |||
981 | if (ndlp->nlp_type & NLP_FCP_TARGET) { | 984 | if (ndlp->nlp_type & NLP_FCP_TARGET) { |
985 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
982 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | 986 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; |
983 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | 987 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); |
984 | } else { | 988 | } else { |
989 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
985 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 990 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
986 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 991 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
987 | } | 992 | } |
@@ -1008,6 +1013,7 @@ lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, | |||
1008 | /* software abort outstanding ADISC */ | 1013 | /* software abort outstanding ADISC */ |
1009 | lpfc_els_abort(phba, ndlp, 1); | 1014 | lpfc_els_abort(phba, ndlp, 1); |
1010 | 1015 | ||
1016 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | ||
1011 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1017 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1012 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1018 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1013 | spin_lock_irq(phba->host->host_lock); | 1019 | spin_lock_irq(phba->host->host_lock); |
@@ -1103,14 +1109,15 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1103 | phba->brd_no, | 1109 | phba->brd_no, |
1104 | did, mb->mbxStatus, phba->hba_state); | 1110 | did, mb->mbxStatus, phba->hba_state); |
1105 | 1111 | ||
1112 | /* Put ndlp in npr list set plogi timer for 1 sec */ | ||
1106 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1113 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1107 | spin_lock_irq(phba->host->host_lock); | 1114 | spin_lock_irq(phba->host->host_lock); |
1108 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1115 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1109 | spin_unlock_irq(phba->host->host_lock); | 1116 | spin_unlock_irq(phba->host->host_lock); |
1117 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
1110 | 1118 | ||
1111 | lpfc_issue_els_logo(phba, ndlp, 0); | 1119 | lpfc_issue_els_logo(phba, ndlp, 0); |
1112 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 1120 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1113 | ndlp->nlp_last_elscmd = (unsigned long)ELS_CMD_PLOGI; | ||
1114 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1121 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1115 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1122 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1116 | return ndlp->nlp_state; | 1123 | return ndlp->nlp_state; |
@@ -1120,10 +1127,12 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1120 | 1127 | ||
1121 | /* Only if we are not a fabric nport do we issue PRLI */ | 1128 | /* Only if we are not a fabric nport do we issue PRLI */ |
1122 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 1129 | if (!(ndlp->nlp_type & NLP_FABRIC)) { |
1130 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1123 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; | 1131 | ndlp->nlp_state = NLP_STE_PRLI_ISSUE; |
1124 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); | 1132 | lpfc_nlp_list(phba, ndlp, NLP_PRLI_LIST); |
1125 | lpfc_issue_els_prli(phba, ndlp, 0); | 1133 | lpfc_issue_els_prli(phba, ndlp, 0); |
1126 | } else { | 1134 | } else { |
1135 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1127 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 1136 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
1128 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 1137 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
1129 | } | 1138 | } |
@@ -1144,6 +1153,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, | |||
1144 | struct lpfc_nodelist * ndlp, void *arg, | 1153 | struct lpfc_nodelist * ndlp, void *arg, |
1145 | uint32_t evt) | 1154 | uint32_t evt) |
1146 | { | 1155 | { |
1156 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | ||
1147 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1157 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1148 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1158 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1149 | spin_lock_irq(phba->host->host_lock); | 1159 | spin_lock_irq(phba->host->host_lock); |
@@ -1233,6 +1243,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1233 | 1243 | ||
1234 | irsp = &rspiocb->iocb; | 1244 | irsp = &rspiocb->iocb; |
1235 | if (irsp->ulpStatus) { | 1245 | if (irsp->ulpStatus) { |
1246 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1236 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; | 1247 | ndlp->nlp_state = NLP_STE_UNMAPPED_NODE; |
1237 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); | 1248 | lpfc_nlp_list(phba, ndlp, NLP_UNMAPPED_LIST); |
1238 | return ndlp->nlp_state; | 1249 | return ndlp->nlp_state; |
@@ -1251,6 +1262,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1251 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; | 1262 | ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE; |
1252 | } | 1263 | } |
1253 | 1264 | ||
1265 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1254 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; | 1266 | ndlp->nlp_state = NLP_STE_MAPPED_NODE; |
1255 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); | 1267 | lpfc_nlp_list(phba, ndlp, NLP_MAPPED_LIST); |
1256 | return ndlp->nlp_state; | 1268 | return ndlp->nlp_state; |
@@ -1308,6 +1320,7 @@ lpfc_device_recov_prli_issue(struct lpfc_hba * phba, | |||
1308 | /* software abort outstanding PRLI */ | 1320 | /* software abort outstanding PRLI */ |
1309 | lpfc_els_abort(phba, ndlp, 1); | 1321 | lpfc_els_abort(phba, ndlp, 1); |
1310 | 1322 | ||
1323 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | ||
1311 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1324 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1312 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1325 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1313 | spin_lock_irq(phba->host->host_lock); | 1326 | spin_lock_irq(phba->host->host_lock); |
@@ -1381,6 +1394,7 @@ static uint32_t | |||
1381 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, | 1394 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, |
1382 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1395 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) |
1383 | { | 1396 | { |
1397 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; | ||
1384 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1398 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1385 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1399 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1386 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; | 1400 | ndlp->nlp_flag &= ~NLP_NPR_2B_DISC; |
@@ -1462,6 +1476,7 @@ lpfc_device_recov_mapped_node(struct lpfc_hba * phba, | |||
1462 | struct lpfc_nodelist * ndlp, void *arg, | 1476 | struct lpfc_nodelist * ndlp, void *arg, |
1463 | uint32_t evt) | 1477 | uint32_t evt) |
1464 | { | 1478 | { |
1479 | ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; | ||
1465 | ndlp->nlp_state = NLP_STE_NPR_NODE; | 1480 | ndlp->nlp_state = NLP_STE_NPR_NODE; |
1466 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); | 1481 | lpfc_nlp_list(phba, ndlp, NLP_NPR_LIST); |
1467 | spin_lock_irq(phba->host->host_lock); | 1482 | spin_lock_irq(phba->host->host_lock); |
@@ -1494,6 +1509,7 @@ lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, | |||
1494 | 1509 | ||
1495 | /* send PLOGI immediately, move to PLOGI issue state */ | 1510 | /* send PLOGI immediately, move to PLOGI issue state */ |
1496 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1511 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1512 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1497 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1513 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1498 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1514 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1499 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1515 | lpfc_issue_els_plogi(phba, ndlp, 0); |
@@ -1521,10 +1537,12 @@ lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, | |||
1521 | spin_lock_irq(phba->host->host_lock); | 1537 | spin_lock_irq(phba->host->host_lock); |
1522 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1538 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1523 | spin_unlock_irq(phba->host->host_lock); | 1539 | spin_unlock_irq(phba->host->host_lock); |
1540 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1524 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1541 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1525 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1542 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1526 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1543 | lpfc_issue_els_adisc(phba, ndlp, 0); |
1527 | } else { | 1544 | } else { |
1545 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1528 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1546 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1529 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1547 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1530 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1548 | lpfc_issue_els_plogi(phba, ndlp, 0); |
@@ -1559,10 +1577,12 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | |||
1559 | 1577 | ||
1560 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1578 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1561 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1579 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1580 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1562 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; | 1581 | ndlp->nlp_state = NLP_STE_ADISC_ISSUE; |
1563 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); | 1582 | lpfc_nlp_list(phba, ndlp, NLP_ADISC_LIST); |
1564 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1583 | lpfc_issue_els_adisc(phba, ndlp, 0); |
1565 | } else { | 1584 | } else { |
1585 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | ||
1566 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; | 1586 | ndlp->nlp_state = NLP_STE_PLOGI_ISSUE; |
1567 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); | 1587 | lpfc_nlp_list(phba, ndlp, NLP_PLOGI_LIST); |
1568 | lpfc_issue_els_plogi(phba, ndlp, 0); | 1588 | lpfc_issue_els_plogi(phba, ndlp, 0); |
@@ -1592,6 +1612,7 @@ lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, | |||
1592 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1612 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1593 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1613 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1594 | spin_unlock_irq(phba->host->host_lock); | 1614 | spin_unlock_irq(phba->host->host_lock); |
1615 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | ||
1595 | } else { | 1616 | } else { |
1596 | spin_lock_irq(phba->host->host_lock); | 1617 | spin_lock_irq(phba->host->host_lock); |
1597 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1618 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
@@ -1681,6 +1702,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, | |||
1681 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) | 1702 | if (!list_empty(&ndlp->els_retry_evt.evt_listp)) |
1682 | list_del_init(&ndlp->els_retry_evt.evt_listp); | 1703 | list_del_init(&ndlp->els_retry_evt.evt_listp); |
1683 | spin_unlock_irq(phba->host->host_lock); | 1704 | spin_unlock_irq(phba->host->host_lock); |
1705 | ndlp->nlp_last_elscmd = 0; | ||
1684 | del_timer_sync(&ndlp->nlp_delayfunc); | 1706 | del_timer_sync(&ndlp->nlp_delayfunc); |
1685 | return ndlp->nlp_state; | 1707 | return ndlp->nlp_state; |
1686 | } | 1708 | } |
@@ -1905,6 +1927,5 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, | |||
1905 | } | 1927 | } |
1906 | if (rc == NLP_STE_FREED_NODE) | 1928 | if (rc == NLP_STE_FREED_NODE) |
1907 | return NLP_STE_FREED_NODE; | 1929 | return NLP_STE_FREED_NODE; |
1908 | ndlp->nlp_state = rc; | ||
1909 | return rc; | 1930 | return rc; |
1910 | } | 1931 | } |