diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-04-25 09:53:08 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-06 10:33:15 -0400 |
commit | 685f0bf7afe087940d34f98ac0fd1df84091d360 (patch) | |
tree | 7e7fbfc856f13a3c4c64e14784b7050812753521 /drivers/scsi/lpfc/lpfc_els.c | |
parent | 329f9bc735b4665d42267259b1612191f72c4d42 (diff) |
[SCSI] lpfc 8.1.12 : Collapse discovery lists to a single node list
Collapse discovery lists to a single node list.
Signed-off-by: James Smart <James.Smart@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.c | 155 |
1 files changed, 72 insertions, 83 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index cb63c350c215..ddf7f225ba5c 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -372,7 +372,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, | |||
372 | } | 372 | } |
373 | lpfc_nlp_put(ndlp); | 373 | lpfc_nlp_put(ndlp); |
374 | 374 | ||
375 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, PT2PT_RemoteID); | 375 | ndlp = lpfc_findnode_did(phba, PT2PT_RemoteID); |
376 | if (!ndlp) { | 376 | if (!ndlp) { |
377 | /* | 377 | /* |
378 | * Cannot find existing Fabric ndlp, so allocate a | 378 | * Cannot find existing Fabric ndlp, so allocate a |
@@ -592,12 +592,12 @@ lpfc_els_abort_flogi(struct lpfc_hba * phba) | |||
592 | } | 592 | } |
593 | 593 | ||
594 | int | 594 | int |
595 | lpfc_initial_flogi(struct lpfc_hba * phba) | 595 | lpfc_initial_flogi(struct lpfc_hba *phba) |
596 | { | 596 | { |
597 | struct lpfc_nodelist *ndlp; | 597 | struct lpfc_nodelist *ndlp; |
598 | 598 | ||
599 | /* First look for the Fabric ndlp */ | 599 | /* First look for the Fabric ndlp */ |
600 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, Fabric_DID); | 600 | ndlp = lpfc_findnode_did(phba, Fabric_DID); |
601 | if (!ndlp) { | 601 | if (!ndlp) { |
602 | /* Cannot find existing Fabric ndlp, so allocate a new one */ | 602 | /* Cannot find existing Fabric ndlp, so allocate a new one */ |
603 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 603 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |
@@ -637,7 +637,7 @@ lpfc_more_plogi(struct lpfc_hba * phba) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | static struct lpfc_nodelist * | 639 | static struct lpfc_nodelist * |
640 | lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, | 640 | lpfc_plogi_confirm_nport(struct lpfc_hba *phba, struct lpfc_dmabuf *prsp, |
641 | struct lpfc_nodelist *ndlp) | 641 | struct lpfc_nodelist *ndlp) |
642 | { | 642 | { |
643 | struct lpfc_nodelist *new_ndlp; | 643 | struct lpfc_nodelist *new_ndlp; |
@@ -654,12 +654,12 @@ lpfc_plogi_confirm_nport(struct lpfc_hba * phba, struct lpfc_dmabuf *prsp, | |||
654 | 654 | ||
655 | lp = (uint32_t *) prsp->virt; | 655 | lp = (uint32_t *) prsp->virt; |
656 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 656 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
657 | memset(name, 0, sizeof (struct lpfc_name)); | 657 | memset(name, 0, sizeof(struct lpfc_name)); |
658 | 658 | ||
659 | /* Now we to find out if the NPort we are logging into, matches the WWPN | 659 | /* Now we find out if the NPort we are logging into, matches the WWPN |
660 | * we have for that ndlp. If not, we have some work to do. | 660 | * we have for that ndlp. If not, we have some work to do. |
661 | */ | 661 | */ |
662 | new_ndlp = lpfc_findnode_wwpn(phba, NLP_SEARCH_ALL, &sp->portName); | 662 | new_ndlp = lpfc_findnode_wwpn(phba, &sp->portName); |
663 | 663 | ||
664 | if (new_ndlp == ndlp) | 664 | if (new_ndlp == ndlp) |
665 | return ndlp; | 665 | return ndlp; |
@@ -705,8 +705,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
705 | cmdiocb->context_un.rsp_iocb = rspiocb; | 705 | cmdiocb->context_un.rsp_iocb = rspiocb; |
706 | 706 | ||
707 | irsp = &rspiocb->iocb; | 707 | irsp = &rspiocb->iocb; |
708 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, | 708 | ndlp = lpfc_findnode_did(phba, irsp->un.elsreq64.remoteID); |
709 | irsp->un.elsreq64.remoteID); | ||
710 | if (!ndlp) | 709 | if (!ndlp) |
711 | goto out; | 710 | goto out; |
712 | 711 | ||
@@ -1408,7 +1407,7 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) | |||
1408 | 1407 | ||
1409 | memcpy(&fp->RportName, &phba->fc_portname, sizeof (struct lpfc_name)); | 1408 | memcpy(&fp->RportName, &phba->fc_portname, sizeof (struct lpfc_name)); |
1410 | memcpy(&fp->RnodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); | 1409 | memcpy(&fp->RnodeName, &phba->fc_nodename, sizeof (struct lpfc_name)); |
1411 | if ((ondlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, nportid))) { | 1410 | if ((ondlp = lpfc_findnode_did(phba, nportid))) { |
1412 | memcpy(&fp->OportName, &ondlp->nlp_portname, | 1411 | memcpy(&fp->OportName, &ondlp->nlp_portname, |
1413 | sizeof (struct lpfc_name)); | 1412 | sizeof (struct lpfc_name)); |
1414 | memcpy(&fp->OnodeName, &ondlp->nlp_nodename, | 1413 | memcpy(&fp->OnodeName, &ondlp->nlp_nodename, |
@@ -1595,7 +1594,7 @@ lpfc_els_retry(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
1595 | else { | 1594 | else { |
1596 | /* We should only hit this case for retrying PLOGI */ | 1595 | /* We should only hit this case for retrying PLOGI */ |
1597 | did = irsp->un.elsreq64.remoteID; | 1596 | did = irsp->un.elsreq64.remoteID; |
1598 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); | 1597 | ndlp = lpfc_findnode_did(phba, did); |
1599 | if (!ndlp && (cmd != ELS_CMD_PLOGI)) | 1598 | if (!ndlp && (cmd != ELS_CMD_PLOGI)) |
1600 | return 1; | 1599 | return 1; |
1601 | } | 1600 | } |
@@ -2291,31 +2290,31 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, | |||
2291 | } | 2290 | } |
2292 | 2291 | ||
2293 | int | 2292 | int |
2294 | lpfc_els_disc_adisc(struct lpfc_hba * phba) | 2293 | lpfc_els_disc_adisc(struct lpfc_hba *phba) |
2295 | { | 2294 | { |
2296 | int sentadisc; | 2295 | int sentadisc; |
2297 | struct lpfc_nodelist *ndlp, *next_ndlp; | 2296 | struct lpfc_nodelist *ndlp, *next_ndlp; |
2298 | 2297 | ||
2299 | sentadisc = 0; | 2298 | sentadisc = 0; |
2300 | /* go thru NPR list and issue any remaining ELS ADISCs */ | 2299 | /* go thru NPR nodes and issue any remaining ELS ADISCs */ |
2301 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | 2300 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { |
2302 | nlp_listp) { | 2301 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
2303 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 2302 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
2304 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 2303 | (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) { |
2305 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 2304 | spin_lock_irq(phba->host->host_lock); |
2306 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2305 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
2307 | lpfc_nlp_set_state(phba, ndlp, | 2306 | spin_unlock_irq(phba->host->host_lock); |
2308 | NLP_STE_ADISC_ISSUE); | 2307 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2309 | lpfc_issue_els_adisc(phba, ndlp, 0); | 2308 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); |
2310 | sentadisc++; | 2309 | lpfc_issue_els_adisc(phba, ndlp, 0); |
2311 | phba->num_disc_nodes++; | 2310 | sentadisc++; |
2312 | if (phba->num_disc_nodes >= | 2311 | phba->num_disc_nodes++; |
2313 | phba->cfg_discovery_threads) { | 2312 | if (phba->num_disc_nodes >= |
2314 | spin_lock_irq(phba->host->host_lock); | 2313 | phba->cfg_discovery_threads) { |
2315 | phba->fc_flag |= FC_NLP_MORE; | 2314 | spin_lock_irq(phba->host->host_lock); |
2316 | spin_unlock_irq(phba->host->host_lock); | 2315 | phba->fc_flag |= FC_NLP_MORE; |
2317 | break; | 2316 | spin_unlock_irq(phba->host->host_lock); |
2318 | } | 2317 | break; |
2319 | } | 2318 | } |
2320 | } | 2319 | } |
2321 | } | 2320 | } |
@@ -2335,24 +2334,22 @@ lpfc_els_disc_plogi(struct lpfc_hba * phba) | |||
2335 | 2334 | ||
2336 | sentplogi = 0; | 2335 | sentplogi = 0; |
2337 | /* go thru NPR list and issue any remaining ELS PLOGIs */ | 2336 | /* go thru NPR list and issue any remaining ELS PLOGIs */ |
2338 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | 2337 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, nlp_listp) { |
2339 | nlp_listp) { | 2338 | if (ndlp->nlp_state == NLP_STE_NPR_NODE && |
2340 | if ((ndlp->nlp_flag & NLP_NPR_2B_DISC) && | 2339 | (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 && |
2341 | (!(ndlp->nlp_flag & NLP_DELAY_TMO))) { | 2340 | (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 && |
2342 | if (!(ndlp->nlp_flag & NLP_NPR_ADISC)) { | 2341 | (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) { |
2343 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2342 | ndlp->nlp_prev_state = ndlp->nlp_state; |
2344 | lpfc_nlp_set_state(phba, ndlp, | 2343 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); |
2345 | NLP_STE_PLOGI_ISSUE); | 2344 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); |
2346 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 2345 | sentplogi++; |
2347 | sentplogi++; | 2346 | phba->num_disc_nodes++; |
2348 | phba->num_disc_nodes++; | 2347 | if (phba->num_disc_nodes >= |
2349 | if (phba->num_disc_nodes >= | 2348 | phba->cfg_discovery_threads) { |
2350 | phba->cfg_discovery_threads) { | 2349 | spin_lock_irq(phba->host->host_lock); |
2351 | spin_lock_irq(phba->host->host_lock); | 2350 | phba->fc_flag |= FC_NLP_MORE; |
2352 | phba->fc_flag |= FC_NLP_MORE; | 2351 | spin_unlock_irq(phba->host->host_lock); |
2353 | spin_unlock_irq(phba->host->host_lock); | 2352 | break; |
2354 | break; | ||
2355 | } | ||
2356 | } | 2353 | } |
2357 | } | 2354 | } |
2358 | } | 2355 | } |
@@ -2456,40 +2453,28 @@ lpfc_rscn_payload_check(struct lpfc_hba * phba, uint32_t did) | |||
2456 | static int | 2453 | static int |
2457 | lpfc_rscn_recovery_check(struct lpfc_hba *phba) | 2454 | lpfc_rscn_recovery_check(struct lpfc_hba *phba) |
2458 | { | 2455 | { |
2459 | struct lpfc_nodelist *ndlp = NULL, *next_ndlp; | 2456 | struct lpfc_nodelist *ndlp = NULL; |
2460 | struct list_head *listp; | ||
2461 | struct list_head *node_list[7]; | ||
2462 | int i; | ||
2463 | 2457 | ||
2464 | /* Look at all nodes effected by pending RSCNs and move | 2458 | /* Look at all nodes effected by pending RSCNs and move |
2465 | * them to NPR list. | 2459 | * them to NPR state. |
2466 | */ | 2460 | */ |
2467 | node_list[0] = &phba->fc_npr_list; /* MUST do this list first */ | ||
2468 | node_list[1] = &phba->fc_nlpmap_list; | ||
2469 | node_list[2] = &phba->fc_nlpunmap_list; | ||
2470 | node_list[3] = &phba->fc_prli_list; | ||
2471 | node_list[4] = &phba->fc_reglogin_list; | ||
2472 | node_list[5] = &phba->fc_adisc_list; | ||
2473 | node_list[6] = &phba->fc_plogi_list; | ||
2474 | for (i = 0; i < 7; i++) { | ||
2475 | listp = node_list[i]; | ||
2476 | if (list_empty(listp)) | ||
2477 | continue; | ||
2478 | 2461 | ||
2479 | list_for_each_entry_safe(ndlp, next_ndlp, listp, nlp_listp) { | 2462 | list_for_each_entry(ndlp, &phba->fc_nodes, nlp_listp) { |
2480 | if (!(lpfc_rscn_payload_check(phba, ndlp->nlp_DID))) | 2463 | if (ndlp->nlp_state == NLP_STE_UNUSED_NODE || |
2481 | continue; | 2464 | lpfc_rscn_payload_check(phba, ndlp->nlp_DID) == 0) |
2465 | continue; | ||
2482 | 2466 | ||
2483 | lpfc_disc_state_machine(phba, ndlp, NULL, | 2467 | lpfc_disc_state_machine(phba, ndlp, NULL, |
2484 | NLP_EVT_DEVICE_RECOVERY); | 2468 | NLP_EVT_DEVICE_RECOVERY); |
2485 | 2469 | ||
2486 | /* Make sure NLP_DELAY_TMO is NOT running | 2470 | /* |
2487 | * after a device recovery event. | 2471 | * Make sure NLP_DELAY_TMO is NOT running after a device |
2488 | */ | 2472 | * recovery event. |
2489 | if (ndlp->nlp_flag & NLP_DELAY_TMO) | 2473 | */ |
2490 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 2474 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
2491 | } | 2475 | lpfc_cancel_retry_delay_tmo(phba, ndlp); |
2492 | } | 2476 | } |
2477 | |||
2493 | return 0; | 2478 | return 0; |
2494 | } | 2479 | } |
2495 | 2480 | ||
@@ -2614,8 +2599,8 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) | |||
2614 | 2599 | ||
2615 | /* To process RSCN, first compare RSCN data with NameServer */ | 2600 | /* To process RSCN, first compare RSCN data with NameServer */ |
2616 | phba->fc_ns_retry = 0; | 2601 | phba->fc_ns_retry = 0; |
2617 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_UNMAPPED, NameServer_DID); | 2602 | ndlp = lpfc_findnode_did(phba, NameServer_DID); |
2618 | if (ndlp) { | 2603 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { |
2619 | /* Good ndlp, issue CT Request to NameServer */ | 2604 | /* Good ndlp, issue CT Request to NameServer */ |
2620 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { | 2605 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == 0) { |
2621 | /* Wait for NameServer query cmpl before we can | 2606 | /* Wait for NameServer query cmpl before we can |
@@ -2625,7 +2610,7 @@ lpfc_els_handle_rscn(struct lpfc_hba * phba) | |||
2625 | } else { | 2610 | } else { |
2626 | /* If login to NameServer does not exist, issue one */ | 2611 | /* If login to NameServer does not exist, issue one */ |
2627 | /* Good status, issue PLOGI to NameServer */ | 2612 | /* Good status, issue PLOGI to NameServer */ |
2628 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); | 2613 | ndlp = lpfc_findnode_did(phba, NameServer_DID); |
2629 | if (ndlp) { | 2614 | if (ndlp) { |
2630 | /* Wait for NameServer login cmpl before we can | 2615 | /* Wait for NameServer login cmpl before we can |
2631 | continue */ | 2616 | continue */ |
@@ -2859,6 +2844,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
2859 | 2844 | ||
2860 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2845 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; |
2861 | phba->fc_stat.elsXmitACC++; | 2846 | phba->fc_stat.elsXmitACC++; |
2847 | |||
2862 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 2848 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
2863 | lpfc_els_free_iocb(phba, elsiocb); | 2849 | lpfc_els_free_iocb(phba, elsiocb); |
2864 | } | 2850 | } |
@@ -3144,8 +3130,9 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3144 | */ | 3130 | */ |
3145 | 3131 | ||
3146 | list_for_each_entry_safe(ndlp, next_ndlp, | 3132 | list_for_each_entry_safe(ndlp, next_ndlp, |
3147 | &phba->fc_npr_list, nlp_listp) { | 3133 | &phba->fc_nodes, nlp_listp) { |
3148 | 3134 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | |
3135 | continue; | ||
3149 | if (ndlp->nlp_type & NLP_FABRIC) { | 3136 | if (ndlp->nlp_type & NLP_FABRIC) { |
3150 | /* | 3137 | /* |
3151 | * Clean up old Fabric, Nameserver and | 3138 | * Clean up old Fabric, Nameserver and |
@@ -3168,8 +3155,10 @@ lpfc_els_rcv_fan(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | |||
3168 | /* Discovery not needed, | 3155 | /* Discovery not needed, |
3169 | * move the nodes to their original state. | 3156 | * move the nodes to their original state. |
3170 | */ | 3157 | */ |
3171 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, | 3158 | list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nodes, |
3172 | nlp_listp) { | 3159 | nlp_listp) { |
3160 | if (ndlp->nlp_state != NLP_STE_NPR_NODE) | ||
3161 | continue; | ||
3173 | 3162 | ||
3174 | switch (ndlp->nlp_prev_state) { | 3163 | switch (ndlp->nlp_prev_state) { |
3175 | case NLP_STE_UNMAPPED_NODE: | 3164 | case NLP_STE_UNMAPPED_NODE: |
@@ -3409,7 +3398,7 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, | |||
3409 | } | 3398 | } |
3410 | 3399 | ||
3411 | did = icmd->un.rcvels.remoteID; | 3400 | did = icmd->un.rcvels.remoteID; |
3412 | ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, did); | 3401 | ndlp = lpfc_findnode_did(phba, did); |
3413 | if (!ndlp) { | 3402 | if (!ndlp) { |
3414 | /* Cannot find existing Fabric ndlp, so allocate a new one */ | 3403 | /* Cannot find existing Fabric ndlp, so allocate a new one */ |
3415 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); | 3404 | ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); |