diff options
author | James Smart <James.Smart@Emulex.Com> | 2008-01-11 01:52:36 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-01-23 12:29:21 -0500 |
commit | 0ff10d46cf0a373c9c855a23cc9383ba4030d8d2 (patch) | |
tree | 111eb8303ad63cecad266d507af4c2c0bfec4d5b /drivers/scsi/lpfc/lpfc_ct.c | |
parent | b18268fc631034882f5f3dd93daa248a3bfdd085 (diff) |
[SCSI] lpfc 8.2.4 : Miscellaneous Discovery/ELS Fixes
Miscellaneous Discovery/ELS Fixes:
- Delay free's of ELS requests if adapter reject conditions
- Fix concurrent PLOGI vs ADISC state handling
- Add retry mechanism for GFF_ID
- Correct some illegal state transitions around RSCN timeouts
- Fix missing return in FAN handling
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 | 83 |
1 files changed, 74 insertions, 9 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index e8bd7c122f1e..c735ed4ad070 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -426,6 +426,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
426 | 426 | ||
427 | lpfc_set_disctmo(vport); | 427 | lpfc_set_disctmo(vport); |
428 | vport->num_disc_nodes = 0; | 428 | vport->num_disc_nodes = 0; |
429 | vport->fc_ns_retry = 0; | ||
429 | 430 | ||
430 | 431 | ||
431 | list_add_tail(&head, &mp->list); | 432 | list_add_tail(&head, &mp->list); |
@@ -506,7 +507,17 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
506 | Did, vport->fc_flag, | 507 | Did, vport->fc_flag, |
507 | vport->fc_rscn_id_cnt); | 508 | vport->fc_rscn_id_cnt); |
508 | 509 | ||
509 | if (lpfc_ns_cmd(vport, | 510 | /* This NPortID was previously |
511 | * a FCP target, * Don't even | ||
512 | * bother to send GFF_ID. | ||
513 | */ | ||
514 | ndlp = lpfc_findnode_did(vport, | ||
515 | Did); | ||
516 | if (ndlp && (ndlp->nlp_type & | ||
517 | NLP_FCP_TARGET)) | ||
518 | lpfc_setup_disc_node | ||
519 | (vport, Did); | ||
520 | else if (lpfc_ns_cmd(vport, | ||
510 | SLI_CTNS_GFF_ID, | 521 | SLI_CTNS_GFF_ID, |
511 | 0, Did) == 0) | 522 | 0, Did) == 0) |
512 | vport->num_disc_nodes++; | 523 | vport->num_disc_nodes++; |
@@ -554,7 +565,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
554 | struct lpfc_dmabuf *outp; | 565 | struct lpfc_dmabuf *outp; |
555 | struct lpfc_sli_ct_request *CTrsp; | 566 | struct lpfc_sli_ct_request *CTrsp; |
556 | struct lpfc_nodelist *ndlp; | 567 | struct lpfc_nodelist *ndlp; |
557 | int rc; | 568 | int rc, retry; |
558 | 569 | ||
559 | /* First save ndlp, before we overwrite it */ | 570 | /* First save ndlp, before we overwrite it */ |
560 | ndlp = cmdiocb->context_un.ndlp; | 571 | ndlp = cmdiocb->context_un.ndlp; |
@@ -585,14 +596,35 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
585 | if (irsp->ulpStatus) { | 596 | if (irsp->ulpStatus) { |
586 | /* Check for retry */ | 597 | /* Check for retry */ |
587 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 598 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
588 | if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || | 599 | retry = 1; |
589 | (irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)) | 600 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { |
601 | switch (irsp->un.ulpWord[4]) { | ||
602 | case IOERR_NO_RESOURCES: | ||
603 | /* We don't increment the retry | ||
604 | * count for this case. | ||
605 | */ | ||
606 | break; | ||
607 | case IOERR_LINK_DOWN: | ||
608 | case IOERR_SLI_ABORTED: | ||
609 | case IOERR_SLI_DOWN: | ||
610 | retry = 0; | ||
611 | break; | ||
612 | default: | ||
613 | vport->fc_ns_retry++; | ||
614 | } | ||
615 | } | ||
616 | else | ||
590 | vport->fc_ns_retry++; | 617 | vport->fc_ns_retry++; |
591 | /* CT command is being retried */ | 618 | |
592 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | 619 | if (retry) { |
620 | /* CT command is being retried */ | ||
621 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | ||
593 | vport->fc_ns_retry, 0); | 622 | vport->fc_ns_retry, 0); |
594 | if (rc == 0) | 623 | if (rc == 0) { |
595 | goto out; | 624 | /* success */ |
625 | goto out; | ||
626 | } | ||
627 | } | ||
596 | } | 628 | } |
597 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 629 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
598 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 630 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -698,7 +730,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
698 | struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; | 730 | struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; |
699 | struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; | 731 | struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; |
700 | struct lpfc_sli_ct_request *CTrsp; | 732 | struct lpfc_sli_ct_request *CTrsp; |
701 | int did; | 733 | int did, rc, retry; |
702 | uint8_t fbits; | 734 | uint8_t fbits; |
703 | struct lpfc_nodelist *ndlp; | 735 | struct lpfc_nodelist *ndlp; |
704 | 736 | ||
@@ -729,6 +761,39 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
729 | } | 761 | } |
730 | } | 762 | } |
731 | else { | 763 | else { |
764 | /* Check for retry */ | ||
765 | if (cmdiocb->retry < LPFC_MAX_NS_RETRY) { | ||
766 | retry = 1; | ||
767 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | ||
768 | switch (irsp->un.ulpWord[4]) { | ||
769 | case IOERR_NO_RESOURCES: | ||
770 | /* We don't increment the retry | ||
771 | * count for this case. | ||
772 | */ | ||
773 | break; | ||
774 | case IOERR_LINK_DOWN: | ||
775 | case IOERR_SLI_ABORTED: | ||
776 | case IOERR_SLI_DOWN: | ||
777 | retry = 0; | ||
778 | break; | ||
779 | default: | ||
780 | cmdiocb->retry++; | ||
781 | } | ||
782 | } | ||
783 | else | ||
784 | cmdiocb->retry++; | ||
785 | |||
786 | if (retry) { | ||
787 | /* CT command is being retried */ | ||
788 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID, | ||
789 | cmdiocb->retry, did); | ||
790 | if (rc == 0) { | ||
791 | /* success */ | ||
792 | lpfc_ct_free_iocb(phba, cmdiocb); | ||
793 | return; | ||
794 | } | ||
795 | } | ||
796 | } | ||
732 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 797 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
733 | "0267 NameServer GFF Rsp " | 798 | "0267 NameServer GFF Rsp " |
734 | "x%x Error (%d %d) Data: x%x x%x\n", | 799 | "x%x Error (%d %d) Data: x%x x%x\n", |