aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
authorJamie Wellnitz <Jamie.Wellnitz@emulex.com>2006-02-28 19:25:28 -0500
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-02-28 20:01:51 -0500
commit5024ab179c13d763f95c8391f45f22309609f479 (patch)
tree7c22b094371c8831f8724d7a2e8580a3ed394c1f /drivers/scsi/lpfc/lpfc_els.c
parent41415862a23f422b80eccc92cf885935139e2415 (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>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c123
1 files changed, 91 insertions, 32 deletions
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
1212out: 1210out:
@@ -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
2975static int 2991static int
2976lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, 2992lpfc_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