diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-04-07 10:15:56 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-04-10 08:52:11 -0400 |
commit | 58da1ffb2b1234e9c6c75013a649c659cc38ebd4 (patch) | |
tree | f159b38ff5c830e10eb90918ef5b42ae71645daa /drivers/scsi/lpfc/lpfc_ct.c | |
parent | b35c07d00751c3d554dd6e582b661ac2e8ffc162 (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.c | 46 |
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", |