diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 304 |
1 files changed, 218 insertions, 86 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index c701e4d611a9..92441ce610ed 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -19,7 +19,7 @@ | |||
19 | *******************************************************************/ | 19 | *******************************************************************/ |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Fibre Channel SCSI LAN Device Driver CT support | 22 | * Fibre Channel SCSI LAN Device Driver CT support: FC Generic Services FC-GS |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include <linux/blkdev.h> | 25 | #include <linux/blkdev.h> |
@@ -57,45 +57,27 @@ | |||
57 | 57 | ||
58 | static char *lpfc_release_version = LPFC_DRIVER_VERSION; | 58 | static char *lpfc_release_version = LPFC_DRIVER_VERSION; |
59 | 59 | ||
60 | /* | ||
61 | * lpfc_ct_unsol_event | ||
62 | */ | ||
63 | static void | 60 | static void |
64 | lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | 61 | lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, |
65 | struct lpfc_dmabuf *mp, uint32_t size) | 62 | struct lpfc_dmabuf *mp, uint32_t size) |
66 | { | 63 | { |
67 | if (!mp) { | 64 | if (!mp) { |
68 | printk(KERN_ERR "%s (%d): Unsolited CT, no buffer, " | 65 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
69 | "piocbq = %p, status = x%x, mp = %p, size = %d\n", | 66 | "0146 Ignoring unsolicted CT No HBQ " |
70 | __FUNCTION__, __LINE__, | 67 | "status = x%x\n", |
71 | piocbq, piocbq->iocb.ulpStatus, mp, size); | 68 | piocbq->iocb.ulpStatus); |
72 | } | 69 | } |
73 | 70 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | |
74 | printk(KERN_ERR "%s (%d): Ignoring unsolicted CT piocbq = %p, " | 71 | "0145 Ignoring unsolicted CT HBQ Size:%d " |
75 | "buffer = %p, size = %d, status = x%x\n", | 72 | "status = x%x\n", |
76 | __FUNCTION__, __LINE__, | 73 | size, piocbq->iocb.ulpStatus); |
77 | piocbq, mp, size, | ||
78 | piocbq->iocb.ulpStatus); | ||
79 | |||
80 | } | 74 | } |
81 | 75 | ||
82 | static void | 76 | static void |
83 | lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | 77 | lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, |
84 | struct lpfc_dmabuf *mp, uint32_t size) | 78 | struct lpfc_dmabuf *mp, uint32_t size) |
85 | { | 79 | { |
86 | if (!mp) { | 80 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, mp, size); |
87 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | ||
88 | "HBQ buffer, piocbq = %p, status = x%x\n", | ||
89 | __FUNCTION__, __LINE__, | ||
90 | piocbq, piocbq->iocb.ulpStatus); | ||
91 | } else { | ||
92 | lpfc_ct_unsol_buffer(phba, piocbq, mp, size); | ||
93 | printk(KERN_ERR "%s (%d): Ignoring unsolicted CT " | ||
94 | "piocbq = %p, buffer = %p, size = %d, " | ||
95 | "status = x%x\n", | ||
96 | __FUNCTION__, __LINE__, | ||
97 | piocbq, mp, size, piocbq->iocb.ulpStatus); | ||
98 | } | ||
99 | } | 81 | } |
100 | 82 | ||
101 | void | 83 | void |
@@ -109,11 +91,8 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
109 | struct lpfc_iocbq *iocbq; | 91 | struct lpfc_iocbq *iocbq; |
110 | dma_addr_t paddr; | 92 | dma_addr_t paddr; |
111 | uint32_t size; | 93 | uint32_t size; |
112 | struct lpfc_dmabuf *bdeBuf1 = piocbq->context2; | 94 | struct list_head head; |
113 | struct lpfc_dmabuf *bdeBuf2 = piocbq->context3; | 95 | struct lpfc_dmabuf *bdeBuf; |
114 | |||
115 | piocbq->context2 = NULL; | ||
116 | piocbq->context3 = NULL; | ||
117 | 96 | ||
118 | if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { | 97 | if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { |
119 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); | 98 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); |
@@ -122,7 +101,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
122 | /* Not enough posted buffers; Try posting more buffers */ | 101 | /* Not enough posted buffers; Try posting more buffers */ |
123 | phba->fc_stat.NoRcvBuf++; | 102 | phba->fc_stat.NoRcvBuf++; |
124 | if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) | 103 | if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) |
125 | lpfc_post_buffer(phba, pring, 0, 1); | 104 | lpfc_post_buffer(phba, pring, 2, 1); |
126 | return; | 105 | return; |
127 | } | 106 | } |
128 | 107 | ||
@@ -133,38 +112,34 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
133 | return; | 112 | return; |
134 | 113 | ||
135 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { | 114 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
136 | list_for_each_entry(iocbq, &piocbq->list, list) { | 115 | INIT_LIST_HEAD(&head); |
116 | list_add_tail(&head, &piocbq->list); | ||
117 | list_for_each_entry(iocbq, &head, list) { | ||
137 | icmd = &iocbq->iocb; | 118 | icmd = &iocbq->iocb; |
138 | if (icmd->ulpBdeCount == 0) { | 119 | if (icmd->ulpBdeCount == 0) |
139 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | ||
140 | "BDE, iocbq = %p, status = x%x\n", | ||
141 | __FUNCTION__, __LINE__, | ||
142 | iocbq, iocbq->iocb.ulpStatus); | ||
143 | continue; | 120 | continue; |
144 | } | 121 | bdeBuf = iocbq->context2; |
145 | 122 | iocbq->context2 = NULL; | |
146 | size = icmd->un.cont64[0].tus.f.bdeSize; | 123 | size = icmd->un.cont64[0].tus.f.bdeSize; |
147 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf1, size); | 124 | lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, size); |
148 | lpfc_in_buf_free(phba, bdeBuf1); | 125 | lpfc_in_buf_free(phba, bdeBuf); |
149 | if (icmd->ulpBdeCount == 2) { | 126 | if (icmd->ulpBdeCount == 2) { |
150 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf2, | 127 | bdeBuf = iocbq->context3; |
151 | size); | 128 | iocbq->context3 = NULL; |
152 | lpfc_in_buf_free(phba, bdeBuf2); | 129 | size = icmd->unsli3.rcvsli3.bde2.tus.f.bdeSize; |
130 | lpfc_ct_unsol_buffer(phba, piocbq, bdeBuf, | ||
131 | size); | ||
132 | lpfc_in_buf_free(phba, bdeBuf); | ||
153 | } | 133 | } |
154 | } | 134 | } |
135 | list_del(&head); | ||
155 | } else { | 136 | } else { |
156 | struct lpfc_iocbq *next; | 137 | struct lpfc_iocbq *next; |
157 | 138 | ||
158 | list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { | 139 | list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { |
159 | icmd = &iocbq->iocb; | 140 | icmd = &iocbq->iocb; |
160 | if (icmd->ulpBdeCount == 0) { | 141 | if (icmd->ulpBdeCount == 0) |
161 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | 142 | lpfc_ct_unsol_buffer(phba, piocbq, NULL, 0); |
162 | "BDE, iocbq = %p, status = x%x\n", | ||
163 | __FUNCTION__, __LINE__, | ||
164 | iocbq, iocbq->iocb.ulpStatus); | ||
165 | continue; | ||
166 | } | ||
167 | |||
168 | for (i = 0; i < icmd->ulpBdeCount; i++) { | 143 | for (i = 0; i < icmd->ulpBdeCount; i++) { |
169 | paddr = getPaddr(icmd->un.cont64[i].addrHigh, | 144 | paddr = getPaddr(icmd->un.cont64[i].addrHigh, |
170 | icmd->un.cont64[i].addrLow); | 145 | icmd->un.cont64[i].addrLow); |
@@ -176,6 +151,7 @@ lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
176 | } | 151 | } |
177 | list_del(&iocbq->list); | 152 | list_del(&iocbq->list); |
178 | lpfc_sli_release_iocbq(phba, iocbq); | 153 | lpfc_sli_release_iocbq(phba, iocbq); |
154 | lpfc_post_buffer(phba, pring, i, 1); | ||
179 | } | 155 | } |
180 | } | 156 | } |
181 | } | 157 | } |
@@ -203,7 +179,7 @@ lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl, | |||
203 | struct lpfc_dmabuf *mp; | 179 | struct lpfc_dmabuf *mp; |
204 | int cnt, i = 0; | 180 | int cnt, i = 0; |
205 | 181 | ||
206 | /* We get chucks of FCELSSIZE */ | 182 | /* We get chunks of FCELSSIZE */ |
207 | cnt = size > FCELSSIZE ? FCELSSIZE: size; | 183 | cnt = size > FCELSSIZE ? FCELSSIZE: size; |
208 | 184 | ||
209 | while (size) { | 185 | while (size) { |
@@ -426,6 +402,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
426 | 402 | ||
427 | lpfc_set_disctmo(vport); | 403 | lpfc_set_disctmo(vport); |
428 | vport->num_disc_nodes = 0; | 404 | vport->num_disc_nodes = 0; |
405 | vport->fc_ns_retry = 0; | ||
429 | 406 | ||
430 | 407 | ||
431 | list_add_tail(&head, &mp->list); | 408 | list_add_tail(&head, &mp->list); |
@@ -458,7 +435,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
458 | ((lpfc_find_vport_by_did(phba, Did) == NULL) || | 435 | ((lpfc_find_vport_by_did(phba, Did) == NULL) || |
459 | vport->cfg_peer_port_login)) { | 436 | vport->cfg_peer_port_login)) { |
460 | if ((vport->port_type != LPFC_NPIV_PORT) || | 437 | if ((vport->port_type != LPFC_NPIV_PORT) || |
461 | (vport->fc_flag & FC_RFF_NOT_SUPPORTED) || | 438 | (!(vport->ct_flags & FC_CT_RFF_ID)) || |
462 | (!vport->cfg_restrict_login)) { | 439 | (!vport->cfg_restrict_login)) { |
463 | ndlp = lpfc_setup_disc_node(vport, Did); | 440 | ndlp = lpfc_setup_disc_node(vport, Did); |
464 | if (ndlp) { | 441 | if (ndlp) { |
@@ -506,7 +483,17 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) | |||
506 | Did, vport->fc_flag, | 483 | Did, vport->fc_flag, |
507 | vport->fc_rscn_id_cnt); | 484 | vport->fc_rscn_id_cnt); |
508 | 485 | ||
509 | if (lpfc_ns_cmd(vport, | 486 | /* This NPortID was previously |
487 | * a FCP target, * Don't even | ||
488 | * bother to send GFF_ID. | ||
489 | */ | ||
490 | ndlp = lpfc_findnode_did(vport, | ||
491 | Did); | ||
492 | if (ndlp && (ndlp->nlp_type & | ||
493 | NLP_FCP_TARGET)) | ||
494 | lpfc_setup_disc_node | ||
495 | (vport, Did); | ||
496 | else if (lpfc_ns_cmd(vport, | ||
510 | SLI_CTNS_GFF_ID, | 497 | SLI_CTNS_GFF_ID, |
511 | 0, Did) == 0) | 498 | 0, Did) == 0) |
512 | vport->num_disc_nodes++; | 499 | vport->num_disc_nodes++; |
@@ -554,7 +541,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
554 | struct lpfc_dmabuf *outp; | 541 | struct lpfc_dmabuf *outp; |
555 | struct lpfc_sli_ct_request *CTrsp; | 542 | struct lpfc_sli_ct_request *CTrsp; |
556 | struct lpfc_nodelist *ndlp; | 543 | struct lpfc_nodelist *ndlp; |
557 | int rc; | 544 | int rc, retry; |
558 | 545 | ||
559 | /* First save ndlp, before we overwrite it */ | 546 | /* First save ndlp, before we overwrite it */ |
560 | ndlp = cmdiocb->context_un.ndlp; | 547 | ndlp = cmdiocb->context_un.ndlp; |
@@ -574,7 +561,6 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
574 | if (vport->load_flag & FC_UNLOADING) | 561 | if (vport->load_flag & FC_UNLOADING) |
575 | goto out; | 562 | goto out; |
576 | 563 | ||
577 | |||
578 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { | 564 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { |
579 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 565 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
580 | "0216 Link event during NS query\n"); | 566 | "0216 Link event during NS query\n"); |
@@ -585,14 +571,35 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
585 | if (irsp->ulpStatus) { | 571 | if (irsp->ulpStatus) { |
586 | /* Check for retry */ | 572 | /* Check for retry */ |
587 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 573 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
588 | if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || | 574 | retry = 1; |
589 | (irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)) | 575 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { |
576 | switch (irsp->un.ulpWord[4]) { | ||
577 | case IOERR_NO_RESOURCES: | ||
578 | /* We don't increment the retry | ||
579 | * count for this case. | ||
580 | */ | ||
581 | break; | ||
582 | case IOERR_LINK_DOWN: | ||
583 | case IOERR_SLI_ABORTED: | ||
584 | case IOERR_SLI_DOWN: | ||
585 | retry = 0; | ||
586 | break; | ||
587 | default: | ||
588 | vport->fc_ns_retry++; | ||
589 | } | ||
590 | } | ||
591 | else | ||
590 | vport->fc_ns_retry++; | 592 | vport->fc_ns_retry++; |
591 | /* CT command is being retried */ | 593 | |
592 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | 594 | if (retry) { |
595 | /* CT command is being retried */ | ||
596 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, | ||
593 | vport->fc_ns_retry, 0); | 597 | vport->fc_ns_retry, 0); |
594 | if (rc == 0) | 598 | if (rc == 0) { |
595 | goto out; | 599 | /* success */ |
600 | goto out; | ||
601 | } | ||
602 | } | ||
596 | } | 603 | } |
597 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 604 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
598 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 605 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -698,7 +705,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; | 705 | struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; |
699 | struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; | 706 | struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; |
700 | struct lpfc_sli_ct_request *CTrsp; | 707 | struct lpfc_sli_ct_request *CTrsp; |
701 | int did; | 708 | int did, rc, retry; |
702 | uint8_t fbits; | 709 | uint8_t fbits; |
703 | struct lpfc_nodelist *ndlp; | 710 | struct lpfc_nodelist *ndlp; |
704 | 711 | ||
@@ -729,6 +736,39 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
729 | } | 736 | } |
730 | } | 737 | } |
731 | else { | 738 | else { |
739 | /* Check for retry */ | ||
740 | if (cmdiocb->retry < LPFC_MAX_NS_RETRY) { | ||
741 | retry = 1; | ||
742 | if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) { | ||
743 | switch (irsp->un.ulpWord[4]) { | ||
744 | case IOERR_NO_RESOURCES: | ||
745 | /* We don't increment the retry | ||
746 | * count for this case. | ||
747 | */ | ||
748 | break; | ||
749 | case IOERR_LINK_DOWN: | ||
750 | case IOERR_SLI_ABORTED: | ||
751 | case IOERR_SLI_DOWN: | ||
752 | retry = 0; | ||
753 | break; | ||
754 | default: | ||
755 | cmdiocb->retry++; | ||
756 | } | ||
757 | } | ||
758 | else | ||
759 | cmdiocb->retry++; | ||
760 | |||
761 | if (retry) { | ||
762 | /* CT command is being retried */ | ||
763 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GFF_ID, | ||
764 | cmdiocb->retry, did); | ||
765 | if (rc == 0) { | ||
766 | /* success */ | ||
767 | lpfc_ct_free_iocb(phba, cmdiocb); | ||
768 | return; | ||
769 | } | ||
770 | } | ||
771 | } | ||
732 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, | 772 | lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY, |
733 | "0267 NameServer GFF Rsp " | 773 | "0267 NameServer GFF Rsp " |
734 | "x%x Error (%d %d) Data: x%x x%x\n", | 774 | "x%x Error (%d %d) Data: x%x x%x\n", |
@@ -778,8 +818,8 @@ out: | |||
778 | 818 | ||
779 | 819 | ||
780 | static void | 820 | static void |
781 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 821 | lpfc_cmpl_ct(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
782 | struct lpfc_iocbq *rspiocb) | 822 | struct lpfc_iocbq *rspiocb) |
783 | { | 823 | { |
784 | struct lpfc_vport *vport = cmdiocb->vport; | 824 | struct lpfc_vport *vport = cmdiocb->vport; |
785 | struct lpfc_dmabuf *inp; | 825 | struct lpfc_dmabuf *inp; |
@@ -809,7 +849,7 @@ lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
809 | 849 | ||
810 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ | 850 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ |
811 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, | 851 | lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY, |
812 | "0209 RFT request completes, latt %d, " | 852 | "0209 CT Request completes, latt %d, " |
813 | "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", | 853 | "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", |
814 | latt, irsp->ulpStatus, | 854 | latt, irsp->ulpStatus, |
815 | CTrsp->CommandResponse.bits.CmdRsp, | 855 | CTrsp->CommandResponse.bits.CmdRsp, |
@@ -848,10 +888,44 @@ out: | |||
848 | } | 888 | } |
849 | 889 | ||
850 | static void | 890 | static void |
891 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | ||
892 | struct lpfc_iocbq *rspiocb) | ||
893 | { | ||
894 | IOCB_t *irsp = &rspiocb->iocb; | ||
895 | struct lpfc_vport *vport = cmdiocb->vport; | ||
896 | |||
897 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
898 | struct lpfc_dmabuf *outp; | ||
899 | struct lpfc_sli_ct_request *CTrsp; | ||
900 | |||
901 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
902 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
903 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
904 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
905 | vport->ct_flags |= FC_CT_RFT_ID; | ||
906 | } | ||
907 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
908 | return; | ||
909 | } | ||
910 | |||
911 | static void | ||
851 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 912 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
852 | struct lpfc_iocbq *rspiocb) | 913 | struct lpfc_iocbq *rspiocb) |
853 | { | 914 | { |
854 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 915 | IOCB_t *irsp = &rspiocb->iocb; |
916 | struct lpfc_vport *vport = cmdiocb->vport; | ||
917 | |||
918 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
919 | struct lpfc_dmabuf *outp; | ||
920 | struct lpfc_sli_ct_request *CTrsp; | ||
921 | |||
922 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
923 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
924 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
925 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
926 | vport->ct_flags |= FC_CT_RNN_ID; | ||
927 | } | ||
928 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
855 | return; | 929 | return; |
856 | } | 930 | } |
857 | 931 | ||
@@ -859,7 +933,20 @@ static void | |||
859 | lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 933 | lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
860 | struct lpfc_iocbq *rspiocb) | 934 | struct lpfc_iocbq *rspiocb) |
861 | { | 935 | { |
862 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 936 | IOCB_t *irsp = &rspiocb->iocb; |
937 | struct lpfc_vport *vport = cmdiocb->vport; | ||
938 | |||
939 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
940 | struct lpfc_dmabuf *outp; | ||
941 | struct lpfc_sli_ct_request *CTrsp; | ||
942 | |||
943 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
944 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
945 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
946 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
947 | vport->ct_flags |= FC_CT_RSPN_ID; | ||
948 | } | ||
949 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
863 | return; | 950 | return; |
864 | } | 951 | } |
865 | 952 | ||
@@ -867,7 +954,32 @@ static void | |||
867 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 954 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
868 | struct lpfc_iocbq *rspiocb) | 955 | struct lpfc_iocbq *rspiocb) |
869 | { | 956 | { |
870 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 957 | IOCB_t *irsp = &rspiocb->iocb; |
958 | struct lpfc_vport *vport = cmdiocb->vport; | ||
959 | |||
960 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
961 | struct lpfc_dmabuf *outp; | ||
962 | struct lpfc_sli_ct_request *CTrsp; | ||
963 | |||
964 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
965 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
966 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
967 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
968 | vport->ct_flags |= FC_CT_RSNN_NN; | ||
969 | } | ||
970 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
971 | return; | ||
972 | } | ||
973 | |||
974 | static void | ||
975 | lpfc_cmpl_ct_cmd_da_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | ||
976 | struct lpfc_iocbq *rspiocb) | ||
977 | { | ||
978 | struct lpfc_vport *vport = cmdiocb->vport; | ||
979 | |||
980 | /* even if it fails we will act as though it succeeded. */ | ||
981 | vport->ct_flags = 0; | ||
982 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
871 | return; | 983 | return; |
872 | } | 984 | } |
873 | 985 | ||
@@ -878,10 +990,17 @@ lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
878 | IOCB_t *irsp = &rspiocb->iocb; | 990 | IOCB_t *irsp = &rspiocb->iocb; |
879 | struct lpfc_vport *vport = cmdiocb->vport; | 991 | struct lpfc_vport *vport = cmdiocb->vport; |
880 | 992 | ||
881 | if (irsp->ulpStatus != IOSTAT_SUCCESS) | 993 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { |
882 | vport->fc_flag |= FC_RFF_NOT_SUPPORTED; | 994 | struct lpfc_dmabuf *outp; |
995 | struct lpfc_sli_ct_request *CTrsp; | ||
883 | 996 | ||
884 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 997 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; |
998 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
999 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
1000 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) | ||
1001 | vport->ct_flags |= FC_CT_RFF_ID; | ||
1002 | } | ||
1003 | lpfc_cmpl_ct(phba, cmdiocb, rspiocb); | ||
885 | return; | 1004 | return; |
886 | } | 1005 | } |
887 | 1006 | ||
@@ -1001,6 +1120,8 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1001 | bpl->tus.f.bdeSize = RSPN_REQUEST_SZ; | 1120 | bpl->tus.f.bdeSize = RSPN_REQUEST_SZ; |
1002 | else if (cmdcode == SLI_CTNS_RSNN_NN) | 1121 | else if (cmdcode == SLI_CTNS_RSNN_NN) |
1003 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; | 1122 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; |
1123 | else if (cmdcode == SLI_CTNS_DA_ID) | ||
1124 | bpl->tus.f.bdeSize = DA_ID_REQUEST_SZ; | ||
1004 | else if (cmdcode == SLI_CTNS_RFF_ID) | 1125 | else if (cmdcode == SLI_CTNS_RFF_ID) |
1005 | bpl->tus.f.bdeSize = RFF_REQUEST_SZ; | 1126 | bpl->tus.f.bdeSize = RFF_REQUEST_SZ; |
1006 | else | 1127 | else |
@@ -1029,31 +1150,34 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1029 | case SLI_CTNS_GFF_ID: | 1150 | case SLI_CTNS_GFF_ID: |
1030 | CtReq->CommandResponse.bits.CmdRsp = | 1151 | CtReq->CommandResponse.bits.CmdRsp = |
1031 | be16_to_cpu(SLI_CTNS_GFF_ID); | 1152 | be16_to_cpu(SLI_CTNS_GFF_ID); |
1032 | CtReq->un.gff.PortId = be32_to_cpu(context); | 1153 | CtReq->un.gff.PortId = cpu_to_be32(context); |
1033 | cmpl = lpfc_cmpl_ct_cmd_gff_id; | 1154 | cmpl = lpfc_cmpl_ct_cmd_gff_id; |
1034 | break; | 1155 | break; |
1035 | 1156 | ||
1036 | case SLI_CTNS_RFT_ID: | 1157 | case SLI_CTNS_RFT_ID: |
1158 | vport->ct_flags &= ~FC_CT_RFT_ID; | ||
1037 | CtReq->CommandResponse.bits.CmdRsp = | 1159 | CtReq->CommandResponse.bits.CmdRsp = |
1038 | be16_to_cpu(SLI_CTNS_RFT_ID); | 1160 | be16_to_cpu(SLI_CTNS_RFT_ID); |
1039 | CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID); | 1161 | CtReq->un.rft.PortId = cpu_to_be32(vport->fc_myDID); |
1040 | CtReq->un.rft.fcpReg = 1; | 1162 | CtReq->un.rft.fcpReg = 1; |
1041 | cmpl = lpfc_cmpl_ct_cmd_rft_id; | 1163 | cmpl = lpfc_cmpl_ct_cmd_rft_id; |
1042 | break; | 1164 | break; |
1043 | 1165 | ||
1044 | case SLI_CTNS_RNN_ID: | 1166 | case SLI_CTNS_RNN_ID: |
1167 | vport->ct_flags &= ~FC_CT_RNN_ID; | ||
1045 | CtReq->CommandResponse.bits.CmdRsp = | 1168 | CtReq->CommandResponse.bits.CmdRsp = |
1046 | be16_to_cpu(SLI_CTNS_RNN_ID); | 1169 | be16_to_cpu(SLI_CTNS_RNN_ID); |
1047 | CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID); | 1170 | CtReq->un.rnn.PortId = cpu_to_be32(vport->fc_myDID); |
1048 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, | 1171 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, |
1049 | sizeof (struct lpfc_name)); | 1172 | sizeof (struct lpfc_name)); |
1050 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; | 1173 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; |
1051 | break; | 1174 | break; |
1052 | 1175 | ||
1053 | case SLI_CTNS_RSPN_ID: | 1176 | case SLI_CTNS_RSPN_ID: |
1177 | vport->ct_flags &= ~FC_CT_RSPN_ID; | ||
1054 | CtReq->CommandResponse.bits.CmdRsp = | 1178 | CtReq->CommandResponse.bits.CmdRsp = |
1055 | be16_to_cpu(SLI_CTNS_RSPN_ID); | 1179 | be16_to_cpu(SLI_CTNS_RSPN_ID); |
1056 | CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID); | 1180 | CtReq->un.rspn.PortId = cpu_to_be32(vport->fc_myDID); |
1057 | size = sizeof(CtReq->un.rspn.symbname); | 1181 | size = sizeof(CtReq->un.rspn.symbname); |
1058 | CtReq->un.rspn.len = | 1182 | CtReq->un.rspn.len = |
1059 | lpfc_vport_symbolic_port_name(vport, | 1183 | lpfc_vport_symbolic_port_name(vport, |
@@ -1061,6 +1185,7 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1061 | cmpl = lpfc_cmpl_ct_cmd_rspn_id; | 1185 | cmpl = lpfc_cmpl_ct_cmd_rspn_id; |
1062 | break; | 1186 | break; |
1063 | case SLI_CTNS_RSNN_NN: | 1187 | case SLI_CTNS_RSNN_NN: |
1188 | vport->ct_flags &= ~FC_CT_RSNN_NN; | ||
1064 | CtReq->CommandResponse.bits.CmdRsp = | 1189 | CtReq->CommandResponse.bits.CmdRsp = |
1065 | be16_to_cpu(SLI_CTNS_RSNN_NN); | 1190 | be16_to_cpu(SLI_CTNS_RSNN_NN); |
1066 | memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, | 1191 | memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, |
@@ -1071,11 +1196,18 @@ lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, | |||
1071 | CtReq->un.rsnn.symbname, size); | 1196 | CtReq->un.rsnn.symbname, size); |
1072 | cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; | 1197 | cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; |
1073 | break; | 1198 | break; |
1199 | case SLI_CTNS_DA_ID: | ||
1200 | /* Implement DA_ID Nameserver request */ | ||
1201 | CtReq->CommandResponse.bits.CmdRsp = | ||
1202 | be16_to_cpu(SLI_CTNS_DA_ID); | ||
1203 | CtReq->un.da_id.port_id = cpu_to_be32(vport->fc_myDID); | ||
1204 | cmpl = lpfc_cmpl_ct_cmd_da_id; | ||
1205 | break; | ||
1074 | case SLI_CTNS_RFF_ID: | 1206 | case SLI_CTNS_RFF_ID: |
1075 | vport->fc_flag &= ~FC_RFF_NOT_SUPPORTED; | 1207 | vport->ct_flags &= ~FC_CT_RFF_ID; |
1076 | CtReq->CommandResponse.bits.CmdRsp = | 1208 | CtReq->CommandResponse.bits.CmdRsp = |
1077 | be16_to_cpu(SLI_CTNS_RFF_ID); | 1209 | be16_to_cpu(SLI_CTNS_RFF_ID); |
1078 | CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);; | 1210 | CtReq->un.rff.PortId = cpu_to_be32(vport->fc_myDID);; |
1079 | CtReq->un.rff.fbits = FC4_FEATURE_INIT; | 1211 | CtReq->un.rff.fbits = FC4_FEATURE_INIT; |
1080 | CtReq->un.rff.type_code = FC_FCP_DATA; | 1212 | CtReq->un.rff.type_code = FC_FCP_DATA; |
1081 | cmpl = lpfc_cmpl_ct_cmd_rff_id; | 1213 | cmpl = lpfc_cmpl_ct_cmd_rff_id; |