aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_ct.c
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2008-04-07 10:15:56 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-04-10 08:52:11 -0400
commit58da1ffb2b1234e9c6c75013a649c659cc38ebd4 (patch)
treef159b38ff5c830e10eb90918ef5b42ae71645daa /drivers/scsi/lpfc/lpfc_ct.c
parentb35c07d00751c3d554dd6e582b661ac2e8ffc162 (diff)
[SCSI] lpfc 8.2.6 : Multiple discovery fixes
Multiple Discovery Fixes: - Fix race on discovery due to link events coinciding with vport_delete. - Use NLP_FABRIC state to filter out switch-based pseudo initiators that reuse the same WWNs. - Correct erroneous setting of DID=0 in lpfc_matchdid() - Correct extra reference count that was in the lookup path for the remoteid from an unsolicited ELS. - Correct double-free bug in els abort path. - Correct FDMI server discovery logic for switch that return a WWN of 0. - Fix bugs in ndlp mgmt when a node changes address - Correct bug that did not delete RSCNs for vports upon link transitions - Fix "0216 Link event during NS query" error which pops up when vports are swapped to different switch ports. - Add sanity checks on ndlp structures - Fix devloss log message to dump WWN correctly - Hold off mgmt commands that were interferring with discovery mailbox cmds - Remove unnecessary FC_ESTABLISH_LINK logic. - Correct some race conditions in the worker thread, resulting in devloss: - Clear the work_port_events field before handling the work port events - Clear the deferred ring event before handling a deferred ring event - Hold the hba lock when waking up the work thread - Send an acc for the rscn even when we aren't going to handle it - Fix locking behavior that was not properly protecting the ACTIVE flag, thus allowing mailbox command order to shift. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_ct.c46
1 files changed, 15 insertions, 31 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c
index 3d0ccd9b341d..b64dc711cd8d 100644
--- a/drivers/scsi/lpfc/lpfc_ct.c
+++ b/drivers/scsi/lpfc/lpfc_ct.c
@@ -438,7 +438,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
438 (!(vport->ct_flags & FC_CT_RFF_ID)) || 438 (!(vport->ct_flags & FC_CT_RFF_ID)) ||
439 (!vport->cfg_restrict_login)) { 439 (!vport->cfg_restrict_login)) {
440 ndlp = lpfc_setup_disc_node(vport, Did); 440 ndlp = lpfc_setup_disc_node(vport, Did);
441 if (ndlp) { 441 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
442 lpfc_debugfs_disc_trc(vport, 442 lpfc_debugfs_disc_trc(vport,
443 LPFC_DISC_TRC_CT, 443 LPFC_DISC_TRC_CT,
444 "Parse GID_FTrsp: " 444 "Parse GID_FTrsp: "
@@ -543,7 +543,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
543 struct lpfc_dmabuf *outp; 543 struct lpfc_dmabuf *outp;
544 struct lpfc_sli_ct_request *CTrsp; 544 struct lpfc_sli_ct_request *CTrsp;
545 struct lpfc_nodelist *ndlp; 545 struct lpfc_nodelist *ndlp;
546 int rc, retry; 546 int rc;
547 547
548 /* First save ndlp, before we overwrite it */ 548 /* First save ndlp, before we overwrite it */
549 ndlp = cmdiocb->context_un.ndlp; 549 ndlp = cmdiocb->context_un.ndlp;
@@ -563,45 +563,29 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
563 if (vport->load_flag & FC_UNLOADING) 563 if (vport->load_flag & FC_UNLOADING)
564 goto out; 564 goto out;
565 565
566 if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { 566 if (lpfc_els_chk_latt(vport)) {
567 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 567 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
568 "0216 Link event during NS query\n"); 568 "0216 Link event during NS query\n");
569 lpfc_vport_set_state(vport, FC_VPORT_FAILED); 569 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
570 goto out; 570 goto out;
571 } 571 }
572 572 if (lpfc_error_lost_link(irsp)) {
573 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
574 "0226 NS query failed due to link event\n");
575 goto out;
576 }
573 if (irsp->ulpStatus) { 577 if (irsp->ulpStatus) {
574 /* Check for retry */ 578 /* Check for retry */
575 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { 579 if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
576 retry = 1; 580 if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
577 if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { 581 irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)
578 switch (irsp->un.ulpWord[4]) {
579 case IOERR_NO_RESOURCES:
580 /* We don't increment the retry
581 * count for this case.
582 */
583 break;
584 case IOERR_LINK_DOWN:
585 case IOERR_SLI_ABORTED:
586 case IOERR_SLI_DOWN:
587 retry = 0;
588 break;
589 default:
590 vport->fc_ns_retry++;
591 }
592 }
593 else
594 vport->fc_ns_retry++; 582 vport->fc_ns_retry++;
595 583
596 if (retry) { 584 /* CT command is being retried */
597 /* CT command is being retried */ 585 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
598 rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
599 vport->fc_ns_retry, 0); 586 vport->fc_ns_retry, 0);
600 if (rc == 0) { 587 if (rc == 0)
601 /* success */ 588 goto out;
602 goto out;
603 }
604 }
605 } 589 }
606 lpfc_vport_set_state(vport, FC_VPORT_FAILED); 590 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
607 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, 591 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -780,7 +764,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
780 764
781 /* This is a target port, unregistered port, or the GFF_ID failed */ 765 /* This is a target port, unregistered port, or the GFF_ID failed */
782 ndlp = lpfc_setup_disc_node(vport, did); 766 ndlp = lpfc_setup_disc_node(vport, did);
783 if (ndlp) { 767 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
784 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, 768 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
785 "0242 Process x%x GFF " 769 "0242 Process x%x GFF "
786 "NameServer Rsp Data: x%x x%x x%x\n", 770 "NameServer Rsp Data: x%x x%x x%x\n",