diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_ct.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_ct.c | 971 |
1 files changed, 675 insertions, 296 deletions
diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 34a9e3bb2614..ae9d6f385a6c 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c | |||
@@ -40,6 +40,8 @@ | |||
40 | #include "lpfc_logmsg.h" | 40 | #include "lpfc_logmsg.h" |
41 | #include "lpfc_crtn.h" | 41 | #include "lpfc_crtn.h" |
42 | #include "lpfc_version.h" | 42 | #include "lpfc_version.h" |
43 | #include "lpfc_vport.h" | ||
44 | #include "lpfc_debugfs.h" | ||
43 | 45 | ||
44 | #define HBA_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver | 46 | #define HBA_PORTSPEED_UNKNOWN 0 /* Unknown - transceiver |
45 | * incapable of reporting */ | 47 | * incapable of reporting */ |
@@ -58,25 +60,69 @@ static char *lpfc_release_version = LPFC_DRIVER_VERSION; | |||
58 | /* | 60 | /* |
59 | * lpfc_ct_unsol_event | 61 | * lpfc_ct_unsol_event |
60 | */ | 62 | */ |
63 | static void | ||
64 | lpfc_ct_unsol_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | ||
65 | struct lpfc_dmabuf *mp, uint32_t size) | ||
66 | { | ||
67 | if (!mp) { | ||
68 | printk(KERN_ERR "%s (%d): Unsolited CT, no buffer, " | ||
69 | "piocbq = %p, status = x%x, mp = %p, size = %d\n", | ||
70 | __FUNCTION__, __LINE__, | ||
71 | piocbq, piocbq->iocb.ulpStatus, mp, size); | ||
72 | } | ||
73 | |||
74 | printk(KERN_ERR "%s (%d): Ignoring unsolicted CT piocbq = %p, " | ||
75 | "buffer = %p, size = %d, status = x%x\n", | ||
76 | __FUNCTION__, __LINE__, | ||
77 | piocbq, mp, size, | ||
78 | piocbq->iocb.ulpStatus); | ||
79 | |||
80 | } | ||
81 | |||
82 | static void | ||
83 | lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq, | ||
84 | struct lpfc_dmabuf *mp, uint32_t size) | ||
85 | { | ||
86 | if (!mp) { | ||
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 | } | ||
100 | |||
61 | void | 101 | void |
62 | lpfc_ct_unsol_event(struct lpfc_hba * phba, | 102 | lpfc_ct_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, |
63 | struct lpfc_sli_ring * pring, struct lpfc_iocbq * piocbq) | 103 | struct lpfc_iocbq *piocbq) |
64 | { | 104 | { |
65 | 105 | ||
66 | struct lpfc_iocbq *next_piocbq; | 106 | struct lpfc_dmabuf *mp = NULL; |
67 | struct lpfc_dmabuf *pmbuf = NULL; | ||
68 | struct lpfc_dmabuf *matp, *next_matp; | ||
69 | uint32_t ctx = 0, size = 0, cnt = 0; | ||
70 | IOCB_t *icmd = &piocbq->iocb; | 107 | IOCB_t *icmd = &piocbq->iocb; |
71 | IOCB_t *save_icmd = icmd; | 108 | int i; |
72 | int i, go_exit = 0; | 109 | struct lpfc_iocbq *iocbq; |
73 | struct list_head head; | 110 | dma_addr_t paddr; |
111 | uint32_t size; | ||
112 | struct lpfc_dmabuf *bdeBuf1 = piocbq->context2; | ||
113 | struct lpfc_dmabuf *bdeBuf2 = piocbq->context3; | ||
114 | |||
115 | piocbq->context2 = NULL; | ||
116 | piocbq->context3 = NULL; | ||
74 | 117 | ||
75 | if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) && | 118 | if (unlikely(icmd->ulpStatus == IOSTAT_NEED_BUFFER)) { |
119 | lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ); | ||
120 | } else if ((icmd->ulpStatus == IOSTAT_LOCAL_REJECT) && | ||
76 | ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) { | 121 | ((icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING)) { |
77 | /* Not enough posted buffers; Try posting more buffers */ | 122 | /* Not enough posted buffers; Try posting more buffers */ |
78 | phba->fc_stat.NoRcvBuf++; | 123 | phba->fc_stat.NoRcvBuf++; |
79 | lpfc_post_buffer(phba, pring, 0, 1); | 124 | if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED)) |
125 | lpfc_post_buffer(phba, pring, 0, 1); | ||
80 | return; | 126 | return; |
81 | } | 127 | } |
82 | 128 | ||
@@ -86,66 +132,56 @@ lpfc_ct_unsol_event(struct lpfc_hba * phba, | |||
86 | if (icmd->ulpBdeCount == 0) | 132 | if (icmd->ulpBdeCount == 0) |
87 | return; | 133 | return; |
88 | 134 | ||
89 | INIT_LIST_HEAD(&head); | 135 | if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) { |
90 | list_add_tail(&head, &piocbq->list); | 136 | list_for_each_entry(iocbq, &piocbq->list, list) { |
91 | 137 | icmd = &iocbq->iocb; | |
92 | list_for_each_entry_safe(piocbq, next_piocbq, &head, list) { | 138 | if (icmd->ulpBdeCount == 0) { |
93 | icmd = &piocbq->iocb; | 139 | printk(KERN_ERR "%s (%d): Unsolited CT, no " |
94 | if (ctx == 0) | 140 | "BDE, iocbq = %p, status = x%x\n", |
95 | ctx = (uint32_t) (icmd->ulpContext); | 141 | __FUNCTION__, __LINE__, |
96 | if (icmd->ulpBdeCount == 0) | 142 | iocbq, iocbq->iocb.ulpStatus); |
97 | continue; | 143 | continue; |
98 | |||
99 | for (i = 0; i < icmd->ulpBdeCount; i++) { | ||
100 | matp = lpfc_sli_ringpostbuf_get(phba, pring, | ||
101 | getPaddr(icmd->un. | ||
102 | cont64[i]. | ||
103 | addrHigh, | ||
104 | icmd->un. | ||
105 | cont64[i]. | ||
106 | addrLow)); | ||
107 | if (!matp) { | ||
108 | /* Insert lpfc log message here */ | ||
109 | lpfc_post_buffer(phba, pring, cnt, 1); | ||
110 | go_exit = 1; | ||
111 | goto ct_unsol_event_exit_piocbq; | ||
112 | } | 144 | } |
113 | 145 | ||
114 | /* Typically for Unsolicited CT requests */ | 146 | size = icmd->un.cont64[0].tus.f.bdeSize; |
115 | if (!pmbuf) { | 147 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf1, size); |
116 | pmbuf = matp; | 148 | lpfc_in_buf_free(phba, bdeBuf1); |
117 | INIT_LIST_HEAD(&pmbuf->list); | 149 | if (icmd->ulpBdeCount == 2) { |
118 | } else | 150 | lpfc_ct_ignore_hbq_buffer(phba, piocbq, bdeBuf2, |
119 | list_add_tail(&matp->list, &pmbuf->list); | 151 | size); |
120 | 152 | lpfc_in_buf_free(phba, bdeBuf2); | |
121 | size += icmd->un.cont64[i].tus.f.bdeSize; | 153 | } |
122 | cnt++; | ||
123 | } | 154 | } |
155 | } else { | ||
156 | struct lpfc_iocbq *next; | ||
157 | |||
158 | list_for_each_entry_safe(iocbq, next, &piocbq->list, list) { | ||
159 | icmd = &iocbq->iocb; | ||
160 | if (icmd->ulpBdeCount == 0) { | ||
161 | printk(KERN_ERR "%s (%d): Unsolited CT, no " | ||
162 | "BDE, iocbq = %p, status = x%x\n", | ||
163 | __FUNCTION__, __LINE__, | ||
164 | iocbq, iocbq->iocb.ulpStatus); | ||
165 | continue; | ||
166 | } | ||
124 | 167 | ||
125 | icmd->ulpBdeCount = 0; | 168 | for (i = 0; i < icmd->ulpBdeCount; i++) { |
126 | } | 169 | paddr = getPaddr(icmd->un.cont64[i].addrHigh, |
127 | 170 | icmd->un.cont64[i].addrLow); | |
128 | lpfc_post_buffer(phba, pring, cnt, 1); | 171 | mp = lpfc_sli_ringpostbuf_get(phba, pring, |
129 | if (save_icmd->ulpStatus) { | 172 | paddr); |
130 | go_exit = 1; | 173 | size = icmd->un.cont64[i].tus.f.bdeSize; |
131 | } | 174 | lpfc_ct_unsol_buffer(phba, piocbq, mp, size); |
132 | 175 | lpfc_in_buf_free(phba, mp); | |
133 | ct_unsol_event_exit_piocbq: | 176 | } |
134 | list_del(&head); | 177 | list_del(&iocbq->list); |
135 | if (pmbuf) { | 178 | lpfc_sli_release_iocbq(phba, iocbq); |
136 | list_for_each_entry_safe(matp, next_matp, &pmbuf->list, list) { | ||
137 | lpfc_mbuf_free(phba, matp->virt, matp->phys); | ||
138 | list_del(&matp->list); | ||
139 | kfree(matp); | ||
140 | } | 179 | } |
141 | lpfc_mbuf_free(phba, pmbuf->virt, pmbuf->phys); | ||
142 | kfree(pmbuf); | ||
143 | } | 180 | } |
144 | return; | ||
145 | } | 181 | } |
146 | 182 | ||
147 | static void | 183 | static void |
148 | lpfc_free_ct_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mlist) | 184 | lpfc_free_ct_rsp(struct lpfc_hba *phba, struct lpfc_dmabuf *mlist) |
149 | { | 185 | { |
150 | struct lpfc_dmabuf *mlast, *next_mlast; | 186 | struct lpfc_dmabuf *mlast, *next_mlast; |
151 | 187 | ||
@@ -160,7 +196,7 @@ lpfc_free_ct_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mlist) | |||
160 | } | 196 | } |
161 | 197 | ||
162 | static struct lpfc_dmabuf * | 198 | static struct lpfc_dmabuf * |
163 | lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, | 199 | lpfc_alloc_ct_rsp(struct lpfc_hba *phba, int cmdcode, struct ulp_bde64 *bpl, |
164 | uint32_t size, int *entries) | 200 | uint32_t size, int *entries) |
165 | { | 201 | { |
166 | struct lpfc_dmabuf *mlist = NULL; | 202 | struct lpfc_dmabuf *mlist = NULL; |
@@ -181,7 +217,8 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, | |||
181 | 217 | ||
182 | INIT_LIST_HEAD(&mp->list); | 218 | INIT_LIST_HEAD(&mp->list); |
183 | 219 | ||
184 | if (cmdcode == be16_to_cpu(SLI_CTNS_GID_FT)) | 220 | if (cmdcode == be16_to_cpu(SLI_CTNS_GID_FT) || |
221 | cmdcode == be16_to_cpu(SLI_CTNS_GFF_ID)) | ||
185 | mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys)); | 222 | mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys)); |
186 | else | 223 | else |
187 | mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys)); | 224 | mp->virt = lpfc_mbuf_alloc(phba, 0, &(mp->phys)); |
@@ -201,8 +238,8 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, | |||
201 | 238 | ||
202 | bpl->tus.f.bdeFlags = BUFF_USE_RCV; | 239 | bpl->tus.f.bdeFlags = BUFF_USE_RCV; |
203 | /* build buffer ptr list for IOCB */ | 240 | /* build buffer ptr list for IOCB */ |
204 | bpl->addrLow = le32_to_cpu( putPaddrLow(mp->phys) ); | 241 | bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) ); |
205 | bpl->addrHigh = le32_to_cpu( putPaddrHigh(mp->phys) ); | 242 | bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) ); |
206 | bpl->tus.f.bdeSize = (uint16_t) cnt; | 243 | bpl->tus.f.bdeSize = (uint16_t) cnt; |
207 | bpl->tus.w = le32_to_cpu(bpl->tus.w); | 244 | bpl->tus.w = le32_to_cpu(bpl->tus.w); |
208 | bpl++; | 245 | bpl++; |
@@ -215,24 +252,49 @@ lpfc_alloc_ct_rsp(struct lpfc_hba * phba, int cmdcode, struct ulp_bde64 * bpl, | |||
215 | return mlist; | 252 | return mlist; |
216 | } | 253 | } |
217 | 254 | ||
255 | int | ||
256 | lpfc_ct_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *ctiocb) | ||
257 | { | ||
258 | struct lpfc_dmabuf *buf_ptr; | ||
259 | |||
260 | if (ctiocb->context1) { | ||
261 | buf_ptr = (struct lpfc_dmabuf *) ctiocb->context1; | ||
262 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
263 | kfree(buf_ptr); | ||
264 | ctiocb->context1 = NULL; | ||
265 | } | ||
266 | if (ctiocb->context2) { | ||
267 | lpfc_free_ct_rsp(phba, (struct lpfc_dmabuf *) ctiocb->context2); | ||
268 | ctiocb->context2 = NULL; | ||
269 | } | ||
270 | |||
271 | if (ctiocb->context3) { | ||
272 | buf_ptr = (struct lpfc_dmabuf *) ctiocb->context3; | ||
273 | lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys); | ||
274 | kfree(buf_ptr); | ||
275 | ctiocb->context1 = NULL; | ||
276 | } | ||
277 | lpfc_sli_release_iocbq(phba, ctiocb); | ||
278 | return 0; | ||
279 | } | ||
280 | |||
218 | static int | 281 | static int |
219 | lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, | 282 | lpfc_gen_req(struct lpfc_vport *vport, struct lpfc_dmabuf *bmp, |
220 | struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp, | 283 | struct lpfc_dmabuf *inp, struct lpfc_dmabuf *outp, |
221 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, | 284 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, |
222 | struct lpfc_iocbq *), | 285 | struct lpfc_iocbq *), |
223 | struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry, | 286 | struct lpfc_nodelist *ndlp, uint32_t usr_flg, uint32_t num_entry, |
224 | uint32_t tmo) | 287 | uint32_t tmo, uint8_t retry) |
225 | { | 288 | { |
226 | 289 | struct lpfc_hba *phba = vport->phba; | |
227 | struct lpfc_sli *psli = &phba->sli; | 290 | struct lpfc_sli *psli = &phba->sli; |
228 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; | 291 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
229 | IOCB_t *icmd; | 292 | IOCB_t *icmd; |
230 | struct lpfc_iocbq *geniocb; | 293 | struct lpfc_iocbq *geniocb; |
294 | int rc; | ||
231 | 295 | ||
232 | /* Allocate buffer for command iocb */ | 296 | /* Allocate buffer for command iocb */ |
233 | spin_lock_irq(phba->host->host_lock); | ||
234 | geniocb = lpfc_sli_get_iocbq(phba); | 297 | geniocb = lpfc_sli_get_iocbq(phba); |
235 | spin_unlock_irq(phba->host->host_lock); | ||
236 | 298 | ||
237 | if (geniocb == NULL) | 299 | if (geniocb == NULL) |
238 | return 1; | 300 | return 1; |
@@ -272,31 +334,40 @@ lpfc_gen_req(struct lpfc_hba *phba, struct lpfc_dmabuf *bmp, | |||
272 | icmd->ulpClass = CLASS3; | 334 | icmd->ulpClass = CLASS3; |
273 | icmd->ulpContext = ndlp->nlp_rpi; | 335 | icmd->ulpContext = ndlp->nlp_rpi; |
274 | 336 | ||
337 | if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) { | ||
338 | /* For GEN_REQUEST64_CR, use the RPI */ | ||
339 | icmd->ulpCt_h = 0; | ||
340 | icmd->ulpCt_l = 0; | ||
341 | } | ||
342 | |||
275 | /* Issue GEN REQ IOCB for NPORT <did> */ | 343 | /* Issue GEN REQ IOCB for NPORT <did> */ |
276 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 344 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
277 | "%d:0119 Issue GEN REQ IOCB for NPORT x%x " | 345 | "%d (%d):0119 Issue GEN REQ IOCB to NPORT x%x " |
278 | "Data: x%x x%x\n", phba->brd_no, icmd->un.ulpWord[5], | 346 | "Data: x%x x%x\n", phba->brd_no, vport->vpi, |
279 | icmd->ulpIoTag, phba->hba_state); | 347 | ndlp->nlp_DID, icmd->ulpIoTag, |
348 | vport->port_state); | ||
280 | geniocb->iocb_cmpl = cmpl; | 349 | geniocb->iocb_cmpl = cmpl; |
281 | geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; | 350 | geniocb->drvrTimeout = icmd->ulpTimeout + LPFC_DRVR_TIMEOUT; |
282 | spin_lock_irq(phba->host->host_lock); | 351 | geniocb->vport = vport; |
283 | if (lpfc_sli_issue_iocb(phba, pring, geniocb, 0) == IOCB_ERROR) { | 352 | geniocb->retry = retry; |
353 | rc = lpfc_sli_issue_iocb(phba, pring, geniocb, 0); | ||
354 | |||
355 | if (rc == IOCB_ERROR) { | ||
284 | lpfc_sli_release_iocbq(phba, geniocb); | 356 | lpfc_sli_release_iocbq(phba, geniocb); |
285 | spin_unlock_irq(phba->host->host_lock); | ||
286 | return 1; | 357 | return 1; |
287 | } | 358 | } |
288 | spin_unlock_irq(phba->host->host_lock); | ||
289 | 359 | ||
290 | return 0; | 360 | return 0; |
291 | } | 361 | } |
292 | 362 | ||
293 | static int | 363 | static int |
294 | lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp, | 364 | lpfc_ct_cmd(struct lpfc_vport *vport, struct lpfc_dmabuf *inmp, |
295 | struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp, | 365 | struct lpfc_dmabuf *bmp, struct lpfc_nodelist *ndlp, |
296 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, | 366 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, |
297 | struct lpfc_iocbq *), | 367 | struct lpfc_iocbq *), |
298 | uint32_t rsp_size) | 368 | uint32_t rsp_size, uint8_t retry) |
299 | { | 369 | { |
370 | struct lpfc_hba *phba = vport->phba; | ||
300 | struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt; | 371 | struct ulp_bde64 *bpl = (struct ulp_bde64 *) bmp->virt; |
301 | struct lpfc_dmabuf *outmp; | 372 | struct lpfc_dmabuf *outmp; |
302 | int cnt = 0, status; | 373 | int cnt = 0, status; |
@@ -310,8 +381,8 @@ lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp, | |||
310 | if (!outmp) | 381 | if (!outmp) |
311 | return -ENOMEM; | 382 | return -ENOMEM; |
312 | 383 | ||
313 | status = lpfc_gen_req(phba, bmp, inmp, outmp, cmpl, ndlp, 0, | 384 | status = lpfc_gen_req(vport, bmp, inmp, outmp, cmpl, ndlp, 0, |
314 | cnt+1, 0); | 385 | cnt+1, 0, retry); |
315 | if (status) { | 386 | if (status) { |
316 | lpfc_free_ct_rsp(phba, outmp); | 387 | lpfc_free_ct_rsp(phba, outmp); |
317 | return -ENOMEM; | 388 | return -ENOMEM; |
@@ -319,20 +390,35 @@ lpfc_ct_cmd(struct lpfc_hba *phba, struct lpfc_dmabuf *inmp, | |||
319 | return 0; | 390 | return 0; |
320 | } | 391 | } |
321 | 392 | ||
393 | static struct lpfc_vport * | ||
394 | lpfc_find_vport_by_did(struct lpfc_hba *phba, uint32_t did) { | ||
395 | |||
396 | struct lpfc_vport *vport_curr; | ||
397 | |||
398 | list_for_each_entry(vport_curr, &phba->port_list, listentry) { | ||
399 | if ((vport_curr->fc_myDID) && | ||
400 | (vport_curr->fc_myDID == did)) | ||
401 | return vport_curr; | ||
402 | } | ||
403 | |||
404 | return NULL; | ||
405 | } | ||
406 | |||
322 | static int | 407 | static int |
323 | lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | 408 | lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size) |
324 | { | 409 | { |
410 | struct lpfc_hba *phba = vport->phba; | ||
325 | struct lpfc_sli_ct_request *Response = | 411 | struct lpfc_sli_ct_request *Response = |
326 | (struct lpfc_sli_ct_request *) mp->virt; | 412 | (struct lpfc_sli_ct_request *) mp->virt; |
327 | struct lpfc_nodelist *ndlp = NULL; | 413 | struct lpfc_nodelist *ndlp = NULL; |
328 | struct lpfc_dmabuf *mlast, *next_mp; | 414 | struct lpfc_dmabuf *mlast, *next_mp; |
329 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; | 415 | uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; |
330 | uint32_t Did; | 416 | uint32_t Did, CTentry; |
331 | uint32_t CTentry; | ||
332 | int Cnt; | 417 | int Cnt; |
333 | struct list_head head; | 418 | struct list_head head; |
334 | 419 | ||
335 | lpfc_set_disctmo(phba); | 420 | lpfc_set_disctmo(vport); |
421 | vport->num_disc_nodes = 0; | ||
336 | 422 | ||
337 | 423 | ||
338 | list_add_tail(&head, &mp->list); | 424 | list_add_tail(&head, &mp->list); |
@@ -350,39 +436,96 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
350 | 436 | ||
351 | /* Loop through entire NameServer list of DIDs */ | 437 | /* Loop through entire NameServer list of DIDs */ |
352 | while (Cnt >= sizeof (uint32_t)) { | 438 | while (Cnt >= sizeof (uint32_t)) { |
353 | |||
354 | /* Get next DID from NameServer List */ | 439 | /* Get next DID from NameServer List */ |
355 | CTentry = *ctptr++; | 440 | CTentry = *ctptr++; |
356 | Did = ((be32_to_cpu(CTentry)) & Mask_DID); | 441 | Did = ((be32_to_cpu(CTentry)) & Mask_DID); |
357 | 442 | ||
358 | ndlp = NULL; | 443 | ndlp = NULL; |
359 | if (Did != phba->fc_myDID) { | 444 | |
360 | /* Check for rscn processing or not */ | 445 | /* |
361 | ndlp = lpfc_setup_disc_node(phba, Did); | 446 | * Check for rscn processing or not |
362 | } | 447 | * To conserve rpi's, filter out addresses for other |
363 | /* Mark all node table entries that are in the | 448 | * vports on the same physical HBAs. |
364 | Nameserver */ | 449 | */ |
365 | if (ndlp) { | 450 | if ((Did != vport->fc_myDID) && |
366 | /* NameServer Rsp */ | 451 | ((lpfc_find_vport_by_did(phba, Did) == NULL) || |
367 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 452 | phba->cfg_peer_port_login)) { |
368 | "%d:0238 Process x%x NameServer" | 453 | if ((vport->port_type != LPFC_NPIV_PORT) || |
369 | " Rsp Data: x%x x%x x%x\n", | 454 | (vport->fc_flag & FC_RFF_NOT_SUPPORTED) || |
370 | phba->brd_no, | 455 | (!phba->cfg_vport_restrict_login)) { |
456 | ndlp = lpfc_setup_disc_node(vport, Did); | ||
457 | if (ndlp) { | ||
458 | lpfc_debugfs_disc_trc(vport, | ||
459 | LPFC_DISC_TRC_CT, | ||
460 | "Parse GID_FTrsp: " | ||
461 | "did:x%x flg:x%x x%x", | ||
371 | Did, ndlp->nlp_flag, | 462 | Did, ndlp->nlp_flag, |
372 | phba->fc_flag, | 463 | vport->fc_flag); |
373 | phba->fc_rscn_id_cnt); | 464 | |
374 | } else { | 465 | lpfc_printf_log(phba, KERN_INFO, |
375 | /* NameServer Rsp */ | 466 | LOG_DISCOVERY, |
376 | lpfc_printf_log(phba, | 467 | "%d (%d):0238 Process " |
377 | KERN_INFO, | 468 | "x%x NameServer Rsp" |
378 | LOG_DISCOVERY, | 469 | "Data: x%x x%x x%x\n", |
379 | "%d:0239 Skip x%x NameServer " | 470 | phba->brd_no, |
380 | "Rsp Data: x%x x%x x%x\n", | 471 | vport->vpi, Did, |
381 | phba->brd_no, | 472 | ndlp->nlp_flag, |
382 | Did, Size, phba->fc_flag, | 473 | vport->fc_flag, |
383 | phba->fc_rscn_id_cnt); | 474 | vport->fc_rscn_id_cnt); |
475 | } else { | ||
476 | lpfc_debugfs_disc_trc(vport, | ||
477 | LPFC_DISC_TRC_CT, | ||
478 | "Skip1 GID_FTrsp: " | ||
479 | "did:x%x flg:x%x cnt:%d", | ||
480 | Did, vport->fc_flag, | ||
481 | vport->fc_rscn_id_cnt); | ||
482 | |||
483 | lpfc_printf_log(phba, KERN_INFO, | ||
484 | LOG_DISCOVERY, | ||
485 | "%d (%d):0239 Skip x%x " | ||
486 | "NameServer Rsp Data: " | ||
487 | "x%x x%x\n", | ||
488 | phba->brd_no, | ||
489 | vport->vpi, Did, | ||
490 | vport->fc_flag, | ||
491 | vport->fc_rscn_id_cnt); | ||
492 | } | ||
493 | |||
494 | } else { | ||
495 | if (!(vport->fc_flag & FC_RSCN_MODE) || | ||
496 | (lpfc_rscn_payload_check(vport, Did))) { | ||
497 | lpfc_debugfs_disc_trc(vport, | ||
498 | LPFC_DISC_TRC_CT, | ||
499 | "Query GID_FTrsp: " | ||
500 | "did:x%x flg:x%x cnt:%d", | ||
501 | Did, vport->fc_flag, | ||
502 | vport->fc_rscn_id_cnt); | ||
503 | |||
504 | if (lpfc_ns_cmd(vport, | ||
505 | SLI_CTNS_GFF_ID, | ||
506 | 0, Did) == 0) | ||
507 | vport->num_disc_nodes++; | ||
508 | } | ||
509 | else { | ||
510 | lpfc_debugfs_disc_trc(vport, | ||
511 | LPFC_DISC_TRC_CT, | ||
512 | "Skip2 GID_FTrsp: " | ||
513 | "did:x%x flg:x%x cnt:%d", | ||
514 | Did, vport->fc_flag, | ||
515 | vport->fc_rscn_id_cnt); | ||
516 | |||
517 | lpfc_printf_log(phba, KERN_INFO, | ||
518 | LOG_DISCOVERY, | ||
519 | "%d (%d):0245 Skip x%x " | ||
520 | "NameServer Rsp Data: " | ||
521 | "x%x x%x\n", | ||
522 | phba->brd_no, | ||
523 | vport->vpi, Did, | ||
524 | vport->fc_flag, | ||
525 | vport->fc_rscn_id_cnt); | ||
526 | } | ||
527 | } | ||
384 | } | 528 | } |
385 | |||
386 | if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY))) | 529 | if (CTentry & (be32_to_cpu(SLI_CT_LAST_ENTRY))) |
387 | goto nsout1; | 530 | goto nsout1; |
388 | Cnt -= sizeof (uint32_t); | 531 | Cnt -= sizeof (uint32_t); |
@@ -393,190 +536,369 @@ lpfc_ns_rsp(struct lpfc_hba * phba, struct lpfc_dmabuf * mp, uint32_t Size) | |||
393 | 536 | ||
394 | nsout1: | 537 | nsout1: |
395 | list_del(&head); | 538 | list_del(&head); |
396 | |||
397 | /* | ||
398 | * The driver has cycled through all Nports in the RSCN payload. | ||
399 | * Complete the handling by cleaning up and marking the | ||
400 | * current driver state. | ||
401 | */ | ||
402 | if (phba->hba_state == LPFC_HBA_READY) { | ||
403 | lpfc_els_flush_rscn(phba); | ||
404 | spin_lock_irq(phba->host->host_lock); | ||
405 | phba->fc_flag |= FC_RSCN_MODE; /* we are still in RSCN mode */ | ||
406 | spin_unlock_irq(phba->host->host_lock); | ||
407 | } | ||
408 | return 0; | 539 | return 0; |
409 | } | 540 | } |
410 | 541 | ||
411 | |||
412 | |||
413 | |||
414 | static void | 542 | static void |
415 | lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 543 | lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
416 | struct lpfc_iocbq * rspiocb) | 544 | struct lpfc_iocbq *rspiocb) |
417 | { | 545 | { |
546 | struct lpfc_vport *vport = cmdiocb->vport; | ||
547 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
418 | IOCB_t *irsp; | 548 | IOCB_t *irsp; |
419 | struct lpfc_sli *psli; | ||
420 | struct lpfc_dmabuf *bmp; | 549 | struct lpfc_dmabuf *bmp; |
421 | struct lpfc_dmabuf *inp; | ||
422 | struct lpfc_dmabuf *outp; | 550 | struct lpfc_dmabuf *outp; |
423 | struct lpfc_nodelist *ndlp; | ||
424 | struct lpfc_sli_ct_request *CTrsp; | 551 | struct lpfc_sli_ct_request *CTrsp; |
552 | int rc; | ||
425 | 553 | ||
426 | psli = &phba->sli; | ||
427 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 554 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
428 | cmdiocb->context_un.rsp_iocb = rspiocb; | 555 | cmdiocb->context_un.rsp_iocb = rspiocb; |
429 | 556 | ||
430 | inp = (struct lpfc_dmabuf *) cmdiocb->context1; | ||
431 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | 557 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; |
432 | bmp = (struct lpfc_dmabuf *) cmdiocb->context3; | 558 | bmp = (struct lpfc_dmabuf *) cmdiocb->context3; |
433 | |||
434 | irsp = &rspiocb->iocb; | 559 | irsp = &rspiocb->iocb; |
435 | if (irsp->ulpStatus) { | ||
436 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | ||
437 | ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) || | ||
438 | (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) { | ||
439 | goto out; | ||
440 | } | ||
441 | 560 | ||
561 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, | ||
562 | "GID_FT cmpl: status:x%x/x%x rtry:%d", | ||
563 | irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_ns_retry); | ||
564 | |||
565 | /* Don't bother processing response if vport is being torn down. */ | ||
566 | if (vport->load_flag & FC_UNLOADING) | ||
567 | goto out; | ||
568 | |||
569 | |||
570 | if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) { | ||
571 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
572 | "%d (%d):0216 Link event during NS query\n", | ||
573 | phba->brd_no, vport->vpi); | ||
574 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
575 | goto out; | ||
576 | } | ||
577 | |||
578 | if (irsp->ulpStatus) { | ||
442 | /* Check for retry */ | 579 | /* Check for retry */ |
443 | if (phba->fc_ns_retry < LPFC_MAX_NS_RETRY) { | 580 | if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) { |
444 | phba->fc_ns_retry++; | 581 | if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || |
582 | (irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)) | ||
583 | vport->fc_ns_retry++; | ||
445 | /* CT command is being retried */ | 584 | /* CT command is being retried */ |
446 | ndlp = lpfc_findnode_did(phba, NameServer_DID); | 585 | rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, |
447 | if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) { | 586 | vport->fc_ns_retry, 0); |
448 | if (lpfc_ns_cmd(phba, ndlp, SLI_CTNS_GID_FT) == | 587 | if (rc == 0) |
449 | 0) { | 588 | goto out; |
450 | goto out; | ||
451 | } | ||
452 | } | ||
453 | } | 589 | } |
590 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | ||
591 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | ||
592 | "%d (%d):0257 GID_FT Query error: 0x%x 0x%x\n", | ||
593 | phba->brd_no, vport->vpi, irsp->ulpStatus, | ||
594 | vport->fc_ns_retry); | ||
454 | } else { | 595 | } else { |
455 | /* Good status, continue checking */ | 596 | /* Good status, continue checking */ |
456 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | 597 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; |
457 | if (CTrsp->CommandResponse.bits.CmdRsp == | 598 | if (CTrsp->CommandResponse.bits.CmdRsp == |
458 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { | 599 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { |
459 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 600 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
460 | "%d:0208 NameServer Rsp " | 601 | "%d (%d):0208 NameServer Rsp " |
461 | "Data: x%x\n", | 602 | "Data: x%x\n", |
462 | phba->brd_no, | 603 | phba->brd_no, vport->vpi, |
463 | phba->fc_flag); | 604 | vport->fc_flag); |
464 | lpfc_ns_rsp(phba, outp, | 605 | lpfc_ns_rsp(vport, outp, |
465 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); | 606 | (uint32_t) (irsp->un.genreq64.bdl.bdeSize)); |
466 | } else if (CTrsp->CommandResponse.bits.CmdRsp == | 607 | } else if (CTrsp->CommandResponse.bits.CmdRsp == |
467 | be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { | 608 | be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { |
468 | /* NameServer Rsp Error */ | 609 | /* NameServer Rsp Error */ |
469 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 610 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
470 | "%d:0240 NameServer Rsp Error " | 611 | "%d (%d):0240 NameServer Rsp Error " |
471 | "Data: x%x x%x x%x x%x\n", | 612 | "Data: x%x x%x x%x x%x\n", |
472 | phba->brd_no, | 613 | phba->brd_no, vport->vpi, |
473 | CTrsp->CommandResponse.bits.CmdRsp, | 614 | CTrsp->CommandResponse.bits.CmdRsp, |
474 | (uint32_t) CTrsp->ReasonCode, | 615 | (uint32_t) CTrsp->ReasonCode, |
475 | (uint32_t) CTrsp->Explanation, | 616 | (uint32_t) CTrsp->Explanation, |
476 | phba->fc_flag); | 617 | vport->fc_flag); |
618 | |||
619 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, | ||
620 | "GID_FT rsp err1 cmd:x%x rsn:x%x exp:x%x", | ||
621 | (uint32_t)CTrsp->CommandResponse.bits.CmdRsp, | ||
622 | (uint32_t) CTrsp->ReasonCode, | ||
623 | (uint32_t) CTrsp->Explanation); | ||
624 | |||
477 | } else { | 625 | } else { |
478 | /* NameServer Rsp Error */ | 626 | /* NameServer Rsp Error */ |
479 | lpfc_printf_log(phba, | 627 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
480 | KERN_INFO, | 628 | "%d (%d):0241 NameServer Rsp Error " |
481 | LOG_DISCOVERY, | ||
482 | "%d:0241 NameServer Rsp Error " | ||
483 | "Data: x%x x%x x%x x%x\n", | 629 | "Data: x%x x%x x%x x%x\n", |
484 | phba->brd_no, | 630 | phba->brd_no, vport->vpi, |
485 | CTrsp->CommandResponse.bits.CmdRsp, | 631 | CTrsp->CommandResponse.bits.CmdRsp, |
486 | (uint32_t) CTrsp->ReasonCode, | 632 | (uint32_t) CTrsp->ReasonCode, |
487 | (uint32_t) CTrsp->Explanation, | 633 | (uint32_t) CTrsp->Explanation, |
488 | phba->fc_flag); | 634 | vport->fc_flag); |
635 | |||
636 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, | ||
637 | "GID_FT rsp err2 cmd:x%x rsn:x%x exp:x%x", | ||
638 | (uint32_t)CTrsp->CommandResponse.bits.CmdRsp, | ||
639 | (uint32_t) CTrsp->ReasonCode, | ||
640 | (uint32_t) CTrsp->Explanation); | ||
489 | } | 641 | } |
490 | } | 642 | } |
491 | /* Link up / RSCN discovery */ | 643 | /* Link up / RSCN discovery */ |
492 | lpfc_disc_start(phba); | 644 | if (vport->num_disc_nodes == 0) { |
645 | /* | ||
646 | * The driver has cycled through all Nports in the RSCN payload. | ||
647 | * Complete the handling by cleaning up and marking the | ||
648 | * current driver state. | ||
649 | */ | ||
650 | if (vport->port_state >= LPFC_DISC_AUTH) { | ||
651 | if (vport->fc_flag & FC_RSCN_MODE) { | ||
652 | lpfc_els_flush_rscn(vport); | ||
653 | spin_lock_irq(shost->host_lock); | ||
654 | vport->fc_flag |= FC_RSCN_MODE; /* RSCN still */ | ||
655 | spin_unlock_irq(shost->host_lock); | ||
656 | } | ||
657 | else | ||
658 | lpfc_els_flush_rscn(vport); | ||
659 | } | ||
660 | |||
661 | lpfc_disc_start(vport); | ||
662 | } | ||
493 | out: | 663 | out: |
494 | lpfc_free_ct_rsp(phba, outp); | 664 | lpfc_ct_free_iocb(phba, cmdiocb); |
495 | lpfc_mbuf_free(phba, inp->virt, inp->phys); | ||
496 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | ||
497 | kfree(inp); | ||
498 | kfree(bmp); | ||
499 | spin_lock_irq(phba->host->host_lock); | ||
500 | lpfc_sli_release_iocbq(phba, cmdiocb); | ||
501 | spin_unlock_irq(phba->host->host_lock); | ||
502 | return; | 665 | return; |
503 | } | 666 | } |
504 | 667 | ||
668 | void | ||
669 | lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | ||
670 | struct lpfc_iocbq *rspiocb) | ||
671 | { | ||
672 | struct lpfc_vport *vport = cmdiocb->vport; | ||
673 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
674 | IOCB_t *irsp = &rspiocb->iocb; | ||
675 | struct lpfc_dmabuf *inp = (struct lpfc_dmabuf *) cmdiocb->context1; | ||
676 | struct lpfc_dmabuf *outp = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
677 | struct lpfc_sli_ct_request *CTrsp; | ||
678 | int did; | ||
679 | uint8_t fbits; | ||
680 | struct lpfc_nodelist *ndlp; | ||
681 | |||
682 | did = ((struct lpfc_sli_ct_request *) inp->virt)->un.gff.PortId; | ||
683 | did = be32_to_cpu(did); | ||
684 | |||
685 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, | ||
686 | "GFF_ID cmpl: status:x%x/x%x did:x%x", | ||
687 | irsp->ulpStatus, irsp->un.ulpWord[4], did); | ||
688 | |||
689 | if (irsp->ulpStatus == IOSTAT_SUCCESS) { | ||
690 | /* Good status, continue checking */ | ||
691 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | ||
692 | fbits = CTrsp->un.gff_acc.fbits[FCP_TYPE_FEATURE_OFFSET]; | ||
693 | |||
694 | if (CTrsp->CommandResponse.bits.CmdRsp == | ||
695 | be16_to_cpu(SLI_CT_RESPONSE_FS_ACC)) { | ||
696 | if ((fbits & FC4_FEATURE_INIT) && | ||
697 | !(fbits & FC4_FEATURE_TARGET)) { | ||
698 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
699 | "%d (%d):0245 Skip x%x GFF " | ||
700 | "NameServer Rsp Data: (init) " | ||
701 | "x%x x%x\n", phba->brd_no, | ||
702 | vport->vpi, did, fbits, | ||
703 | vport->fc_rscn_id_cnt); | ||
704 | goto out; | ||
705 | } | ||
706 | } | ||
707 | } | ||
708 | else { | ||
709 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
710 | "%d (%d):0267 NameServer GFF Rsp" | ||
711 | " x%x Error (%d %d) Data: x%x x%x\n", | ||
712 | phba->brd_no, vport->vpi, did, | ||
713 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
714 | vport->fc_flag, vport->fc_rscn_id_cnt) | ||
715 | } | ||
716 | |||
717 | /* This is a target port, unregistered port, or the GFF_ID failed */ | ||
718 | ndlp = lpfc_setup_disc_node(vport, did); | ||
719 | if (ndlp) { | ||
720 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
721 | "%d (%d):0242 Process x%x GFF " | ||
722 | "NameServer Rsp Data: x%x x%x x%x\n", | ||
723 | phba->brd_no, vport->vpi, | ||
724 | did, ndlp->nlp_flag, vport->fc_flag, | ||
725 | vport->fc_rscn_id_cnt); | ||
726 | } else { | ||
727 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
728 | "%d (%d):0243 Skip x%x GFF " | ||
729 | "NameServer Rsp Data: x%x x%x\n", | ||
730 | phba->brd_no, vport->vpi, did, | ||
731 | vport->fc_flag, vport->fc_rscn_id_cnt); | ||
732 | } | ||
733 | out: | ||
734 | /* Link up / RSCN discovery */ | ||
735 | if (vport->num_disc_nodes) | ||
736 | vport->num_disc_nodes--; | ||
737 | if (vport->num_disc_nodes == 0) { | ||
738 | /* | ||
739 | * The driver has cycled through all Nports in the RSCN payload. | ||
740 | * Complete the handling by cleaning up and marking the | ||
741 | * current driver state. | ||
742 | */ | ||
743 | if (vport->port_state >= LPFC_DISC_AUTH) { | ||
744 | if (vport->fc_flag & FC_RSCN_MODE) { | ||
745 | lpfc_els_flush_rscn(vport); | ||
746 | spin_lock_irq(shost->host_lock); | ||
747 | vport->fc_flag |= FC_RSCN_MODE; /* RSCN still */ | ||
748 | spin_unlock_irq(shost->host_lock); | ||
749 | } | ||
750 | else | ||
751 | lpfc_els_flush_rscn(vport); | ||
752 | } | ||
753 | lpfc_disc_start(vport); | ||
754 | } | ||
755 | lpfc_ct_free_iocb(phba, cmdiocb); | ||
756 | return; | ||
757 | } | ||
758 | |||
759 | |||
505 | static void | 760 | static void |
506 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 761 | lpfc_cmpl_ct_cmd_rft_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
507 | struct lpfc_iocbq * rspiocb) | 762 | struct lpfc_iocbq *rspiocb) |
508 | { | 763 | { |
509 | struct lpfc_sli *psli; | 764 | struct lpfc_vport *vport = cmdiocb->vport; |
510 | struct lpfc_dmabuf *bmp; | ||
511 | struct lpfc_dmabuf *inp; | 765 | struct lpfc_dmabuf *inp; |
512 | struct lpfc_dmabuf *outp; | 766 | struct lpfc_dmabuf *outp; |
513 | IOCB_t *irsp; | 767 | IOCB_t *irsp; |
514 | struct lpfc_sli_ct_request *CTrsp; | 768 | struct lpfc_sli_ct_request *CTrsp; |
769 | int cmdcode, rc; | ||
770 | uint8_t retry; | ||
771 | uint32_t latt; | ||
515 | 772 | ||
516 | psli = &phba->sli; | ||
517 | /* we pass cmdiocb to state machine which needs rspiocb as well */ | 773 | /* we pass cmdiocb to state machine which needs rspiocb as well */ |
518 | cmdiocb->context_un.rsp_iocb = rspiocb; | 774 | cmdiocb->context_un.rsp_iocb = rspiocb; |
519 | 775 | ||
520 | inp = (struct lpfc_dmabuf *) cmdiocb->context1; | 776 | inp = (struct lpfc_dmabuf *) cmdiocb->context1; |
521 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; | 777 | outp = (struct lpfc_dmabuf *) cmdiocb->context2; |
522 | bmp = (struct lpfc_dmabuf *) cmdiocb->context3; | ||
523 | irsp = &rspiocb->iocb; | 778 | irsp = &rspiocb->iocb; |
524 | 779 | ||
780 | cmdcode = be16_to_cpu(((struct lpfc_sli_ct_request *) inp->virt)-> | ||
781 | CommandResponse.bits.CmdRsp); | ||
525 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; | 782 | CTrsp = (struct lpfc_sli_ct_request *) outp->virt; |
526 | 783 | ||
784 | latt = lpfc_els_chk_latt(vport); | ||
785 | |||
527 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ | 786 | /* RFT request completes status <ulpStatus> CmdRsp <CmdRsp> */ |
528 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | 787 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
529 | "%d:0209 RFT request completes ulpStatus x%x " | 788 | "%d (%d):0209 RFT request completes, latt %d, " |
530 | "CmdRsp x%x\n", phba->brd_no, irsp->ulpStatus, | 789 | "ulpStatus x%x CmdRsp x%x, Context x%x, Tag x%x\n", |
531 | CTrsp->CommandResponse.bits.CmdRsp); | 790 | phba->brd_no, vport->vpi, latt, irsp->ulpStatus, |
791 | CTrsp->CommandResponse.bits.CmdRsp, | ||
792 | cmdiocb->iocb.ulpContext, cmdiocb->iocb.ulpIoTag); | ||
532 | 793 | ||
533 | lpfc_free_ct_rsp(phba, outp); | 794 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, |
534 | lpfc_mbuf_free(phba, inp->virt, inp->phys); | 795 | "CT cmd cmpl: status:x%x/x%x cmd:x%x", |
535 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 796 | irsp->ulpStatus, irsp->un.ulpWord[4], cmdcode); |
536 | kfree(inp); | 797 | |
537 | kfree(bmp); | 798 | if (irsp->ulpStatus) { |
538 | spin_lock_irq(phba->host->host_lock); | 799 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, |
539 | lpfc_sli_release_iocbq(phba, cmdiocb); | 800 | "%d (%d):0268 NS cmd %x Error (%d %d)\n", |
540 | spin_unlock_irq(phba->host->host_lock); | 801 | phba->brd_no, vport->vpi, cmdcode, |
802 | irsp->ulpStatus, irsp->un.ulpWord[4]); | ||
803 | |||
804 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | ||
805 | ((irsp->un.ulpWord[4] == IOERR_SLI_DOWN) || | ||
806 | (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) | ||
807 | goto out; | ||
808 | |||
809 | retry = cmdiocb->retry; | ||
810 | if (retry >= LPFC_MAX_NS_RETRY) | ||
811 | goto out; | ||
812 | |||
813 | retry++; | ||
814 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
815 | "%d (%d):0216 Retrying NS cmd %x\n", | ||
816 | phba->brd_no, vport->vpi, cmdcode); | ||
817 | rc = lpfc_ns_cmd(vport, cmdcode, retry, 0); | ||
818 | if (rc == 0) | ||
819 | goto out; | ||
820 | } | ||
821 | |||
822 | out: | ||
823 | lpfc_ct_free_iocb(phba, cmdiocb); | ||
541 | return; | 824 | return; |
542 | } | 825 | } |
543 | 826 | ||
544 | static void | 827 | static void |
545 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 828 | lpfc_cmpl_ct_cmd_rnn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
546 | struct lpfc_iocbq * rspiocb) | 829 | struct lpfc_iocbq *rspiocb) |
547 | { | 830 | { |
548 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 831 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); |
549 | return; | 832 | return; |
550 | } | 833 | } |
551 | 834 | ||
552 | static void | 835 | static void |
553 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 836 | lpfc_cmpl_ct_cmd_rspn_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
554 | struct lpfc_iocbq * rspiocb) | 837 | struct lpfc_iocbq *rspiocb) |
555 | { | 838 | { |
556 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 839 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); |
557 | return; | 840 | return; |
558 | } | 841 | } |
559 | 842 | ||
560 | static void | 843 | static void |
561 | lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, | 844 | lpfc_cmpl_ct_cmd_rsnn_nn(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
562 | struct lpfc_iocbq * rspiocb) | 845 | struct lpfc_iocbq *rspiocb) |
563 | { | 846 | { |
564 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); | 847 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); |
565 | return; | 848 | return; |
566 | } | 849 | } |
567 | 850 | ||
568 | void | 851 | static void |
569 | lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) | 852 | lpfc_cmpl_ct_cmd_rff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
853 | struct lpfc_iocbq *rspiocb) | ||
570 | { | 854 | { |
571 | char fwrev[16]; | 855 | IOCB_t *irsp = &rspiocb->iocb; |
856 | struct lpfc_vport *vport = cmdiocb->vport; | ||
572 | 857 | ||
573 | lpfc_decode_firmware_rev(phba, fwrev, 0); | 858 | if (irsp->ulpStatus != IOSTAT_SUCCESS) |
859 | vport->fc_flag |= FC_RFF_NOT_SUPPORTED; | ||
574 | 860 | ||
575 | sprintf(symbp, "Emulex %s FV%s DV%s", phba->ModelName, | 861 | lpfc_cmpl_ct_cmd_rft_id(phba, cmdiocb, rspiocb); |
576 | fwrev, lpfc_release_version); | ||
577 | return; | 862 | return; |
578 | } | 863 | } |
579 | 864 | ||
865 | int | ||
866 | lpfc_vport_symbolic_port_name(struct lpfc_vport *vport, char *symbol, | ||
867 | size_t size) | ||
868 | { | ||
869 | int n; | ||
870 | uint8_t *wwn = vport->phba->wwpn; | ||
871 | |||
872 | n = snprintf(symbol, size, | ||
873 | "Emulex PPN-%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", | ||
874 | wwn[0], wwn[1], wwn[2], wwn[3], | ||
875 | wwn[4], wwn[5], wwn[6], wwn[7]); | ||
876 | |||
877 | if (vport->port_type == LPFC_PHYSICAL_PORT) | ||
878 | return n; | ||
879 | |||
880 | if (n < size) | ||
881 | n += snprintf(symbol + n, size - n, " VPort-%d", vport->vpi); | ||
882 | |||
883 | if (n < size && vport->vname) | ||
884 | n += snprintf(symbol + n, size - n, " VName-%s", vport->vname); | ||
885 | return n; | ||
886 | } | ||
887 | |||
888 | int | ||
889 | lpfc_vport_symbolic_node_name(struct lpfc_vport *vport, char *symbol, | ||
890 | size_t size) | ||
891 | { | ||
892 | char fwrev[16]; | ||
893 | int n; | ||
894 | |||
895 | lpfc_decode_firmware_rev(vport->phba, fwrev, 0); | ||
896 | |||
897 | n = snprintf(symbol, size, "Emulex %s FV%s DV%s", | ||
898 | vport->phba->ModelName, fwrev, lpfc_release_version); | ||
899 | return n; | ||
900 | } | ||
901 | |||
580 | /* | 902 | /* |
581 | * lpfc_ns_cmd | 903 | * lpfc_ns_cmd |
582 | * Description: | 904 | * Description: |
@@ -585,55 +907,76 @@ lpfc_get_hba_sym_node_name(struct lpfc_hba * phba, uint8_t * symbp) | |||
585 | * LI_CTNS_RFT_ID | 907 | * LI_CTNS_RFT_ID |
586 | */ | 908 | */ |
587 | int | 909 | int |
588 | lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | 910 | lpfc_ns_cmd(struct lpfc_vport *vport, int cmdcode, |
911 | uint8_t retry, uint32_t context) | ||
589 | { | 912 | { |
913 | struct lpfc_nodelist * ndlp; | ||
914 | struct lpfc_hba *phba = vport->phba; | ||
590 | struct lpfc_dmabuf *mp, *bmp; | 915 | struct lpfc_dmabuf *mp, *bmp; |
591 | struct lpfc_sli_ct_request *CtReq; | 916 | struct lpfc_sli_ct_request *CtReq; |
592 | struct ulp_bde64 *bpl; | 917 | struct ulp_bde64 *bpl; |
593 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, | 918 | void (*cmpl) (struct lpfc_hba *, struct lpfc_iocbq *, |
594 | struct lpfc_iocbq *) = NULL; | 919 | struct lpfc_iocbq *) = NULL; |
595 | uint32_t rsp_size = 1024; | 920 | uint32_t rsp_size = 1024; |
921 | size_t size; | ||
922 | int rc = 0; | ||
923 | |||
924 | ndlp = lpfc_findnode_did(vport, NameServer_DID); | ||
925 | if (ndlp == NULL || ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) { | ||
926 | rc=1; | ||
927 | goto ns_cmd_exit; | ||
928 | } | ||
596 | 929 | ||
597 | /* fill in BDEs for command */ | 930 | /* fill in BDEs for command */ |
598 | /* Allocate buffer for command payload */ | 931 | /* Allocate buffer for command payload */ |
599 | mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); | 932 | mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); |
600 | if (!mp) | 933 | if (!mp) { |
934 | rc=2; | ||
601 | goto ns_cmd_exit; | 935 | goto ns_cmd_exit; |
936 | } | ||
602 | 937 | ||
603 | INIT_LIST_HEAD(&mp->list); | 938 | INIT_LIST_HEAD(&mp->list); |
604 | mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys)); | 939 | mp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(mp->phys)); |
605 | if (!mp->virt) | 940 | if (!mp->virt) { |
941 | rc=3; | ||
606 | goto ns_cmd_free_mp; | 942 | goto ns_cmd_free_mp; |
943 | } | ||
607 | 944 | ||
608 | /* Allocate buffer for Buffer ptr list */ | 945 | /* Allocate buffer for Buffer ptr list */ |
609 | bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); | 946 | bmp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL); |
610 | if (!bmp) | 947 | if (!bmp) { |
948 | rc=4; | ||
611 | goto ns_cmd_free_mpvirt; | 949 | goto ns_cmd_free_mpvirt; |
950 | } | ||
612 | 951 | ||
613 | INIT_LIST_HEAD(&bmp->list); | 952 | INIT_LIST_HEAD(&bmp->list); |
614 | bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys)); | 953 | bmp->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &(bmp->phys)); |
615 | if (!bmp->virt) | 954 | if (!bmp->virt) { |
955 | rc=5; | ||
616 | goto ns_cmd_free_bmp; | 956 | goto ns_cmd_free_bmp; |
957 | } | ||
617 | 958 | ||
618 | /* NameServer Req */ | 959 | /* NameServer Req */ |
619 | lpfc_printf_log(phba, | 960 | lpfc_printf_log(phba, KERN_INFO ,LOG_DISCOVERY, |
620 | KERN_INFO, | 961 | "%d (%d):0236 NameServer Req Data: x%x x%x x%x\n", |
621 | LOG_DISCOVERY, | 962 | phba->brd_no, vport->vpi, cmdcode, vport->fc_flag, |
622 | "%d:0236 NameServer Req Data: x%x x%x x%x\n", | 963 | vport->fc_rscn_id_cnt); |
623 | phba->brd_no, cmdcode, phba->fc_flag, | ||
624 | phba->fc_rscn_id_cnt); | ||
625 | 964 | ||
626 | bpl = (struct ulp_bde64 *) bmp->virt; | 965 | bpl = (struct ulp_bde64 *) bmp->virt; |
627 | memset(bpl, 0, sizeof(struct ulp_bde64)); | 966 | memset(bpl, 0, sizeof(struct ulp_bde64)); |
628 | bpl->addrHigh = le32_to_cpu( putPaddrHigh(mp->phys) ); | 967 | bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) ); |
629 | bpl->addrLow = le32_to_cpu( putPaddrLow(mp->phys) ); | 968 | bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) ); |
630 | bpl->tus.f.bdeFlags = 0; | 969 | bpl->tus.f.bdeFlags = 0; |
631 | if (cmdcode == SLI_CTNS_GID_FT) | 970 | if (cmdcode == SLI_CTNS_GID_FT) |
632 | bpl->tus.f.bdeSize = GID_REQUEST_SZ; | 971 | bpl->tus.f.bdeSize = GID_REQUEST_SZ; |
972 | else if (cmdcode == SLI_CTNS_GFF_ID) | ||
973 | bpl->tus.f.bdeSize = GFF_REQUEST_SZ; | ||
633 | else if (cmdcode == SLI_CTNS_RFT_ID) | 974 | else if (cmdcode == SLI_CTNS_RFT_ID) |
634 | bpl->tus.f.bdeSize = RFT_REQUEST_SZ; | 975 | bpl->tus.f.bdeSize = RFT_REQUEST_SZ; |
635 | else if (cmdcode == SLI_CTNS_RNN_ID) | 976 | else if (cmdcode == SLI_CTNS_RNN_ID) |
636 | bpl->tus.f.bdeSize = RNN_REQUEST_SZ; | 977 | bpl->tus.f.bdeSize = RNN_REQUEST_SZ; |
978 | else if (cmdcode == SLI_CTNS_RSPN_ID) | ||
979 | bpl->tus.f.bdeSize = RSPN_REQUEST_SZ; | ||
637 | else if (cmdcode == SLI_CTNS_RSNN_NN) | 980 | else if (cmdcode == SLI_CTNS_RSNN_NN) |
638 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; | 981 | bpl->tus.f.bdeSize = RSNN_REQUEST_SZ; |
639 | else if (cmdcode == SLI_CTNS_RFF_ID) | 982 | else if (cmdcode == SLI_CTNS_RFF_ID) |
@@ -654,56 +997,78 @@ lpfc_ns_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
654 | CtReq->CommandResponse.bits.CmdRsp = | 997 | CtReq->CommandResponse.bits.CmdRsp = |
655 | be16_to_cpu(SLI_CTNS_GID_FT); | 998 | be16_to_cpu(SLI_CTNS_GID_FT); |
656 | CtReq->un.gid.Fc4Type = SLI_CTPT_FCP; | 999 | CtReq->un.gid.Fc4Type = SLI_CTPT_FCP; |
657 | if (phba->hba_state < LPFC_HBA_READY) | 1000 | if (vport->port_state < LPFC_NS_QRY) |
658 | phba->hba_state = LPFC_NS_QRY; | 1001 | vport->port_state = LPFC_NS_QRY; |
659 | lpfc_set_disctmo(phba); | 1002 | lpfc_set_disctmo(vport); |
660 | cmpl = lpfc_cmpl_ct_cmd_gid_ft; | 1003 | cmpl = lpfc_cmpl_ct_cmd_gid_ft; |
661 | rsp_size = FC_MAX_NS_RSP; | 1004 | rsp_size = FC_MAX_NS_RSP; |
662 | break; | 1005 | break; |
663 | 1006 | ||
1007 | case SLI_CTNS_GFF_ID: | ||
1008 | CtReq->CommandResponse.bits.CmdRsp = | ||
1009 | be16_to_cpu(SLI_CTNS_GFF_ID); | ||
1010 | CtReq->un.gff.PortId = be32_to_cpu(context); | ||
1011 | cmpl = lpfc_cmpl_ct_cmd_gff_id; | ||
1012 | break; | ||
1013 | |||
664 | case SLI_CTNS_RFT_ID: | 1014 | case SLI_CTNS_RFT_ID: |
665 | CtReq->CommandResponse.bits.CmdRsp = | 1015 | CtReq->CommandResponse.bits.CmdRsp = |
666 | be16_to_cpu(SLI_CTNS_RFT_ID); | 1016 | be16_to_cpu(SLI_CTNS_RFT_ID); |
667 | CtReq->un.rft.PortId = be32_to_cpu(phba->fc_myDID); | 1017 | CtReq->un.rft.PortId = be32_to_cpu(vport->fc_myDID); |
668 | CtReq->un.rft.fcpReg = 1; | 1018 | CtReq->un.rft.fcpReg = 1; |
669 | cmpl = lpfc_cmpl_ct_cmd_rft_id; | 1019 | cmpl = lpfc_cmpl_ct_cmd_rft_id; |
670 | break; | 1020 | break; |
671 | 1021 | ||
672 | case SLI_CTNS_RFF_ID: | ||
673 | CtReq->CommandResponse.bits.CmdRsp = | ||
674 | be16_to_cpu(SLI_CTNS_RFF_ID); | ||
675 | CtReq->un.rff.PortId = be32_to_cpu(phba->fc_myDID); | ||
676 | CtReq->un.rff.feature_res = 0; | ||
677 | CtReq->un.rff.feature_tgt = 0; | ||
678 | CtReq->un.rff.type_code = FC_FCP_DATA; | ||
679 | CtReq->un.rff.feature_init = 1; | ||
680 | cmpl = lpfc_cmpl_ct_cmd_rff_id; | ||
681 | break; | ||
682 | |||
683 | case SLI_CTNS_RNN_ID: | 1022 | case SLI_CTNS_RNN_ID: |
684 | CtReq->CommandResponse.bits.CmdRsp = | 1023 | CtReq->CommandResponse.bits.CmdRsp = |
685 | be16_to_cpu(SLI_CTNS_RNN_ID); | 1024 | be16_to_cpu(SLI_CTNS_RNN_ID); |
686 | CtReq->un.rnn.PortId = be32_to_cpu(phba->fc_myDID); | 1025 | CtReq->un.rnn.PortId = be32_to_cpu(vport->fc_myDID); |
687 | memcpy(CtReq->un.rnn.wwnn, &phba->fc_nodename, | 1026 | memcpy(CtReq->un.rnn.wwnn, &vport->fc_nodename, |
688 | sizeof (struct lpfc_name)); | 1027 | sizeof (struct lpfc_name)); |
689 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; | 1028 | cmpl = lpfc_cmpl_ct_cmd_rnn_id; |
690 | break; | 1029 | break; |
691 | 1030 | ||
1031 | case SLI_CTNS_RSPN_ID: | ||
1032 | CtReq->CommandResponse.bits.CmdRsp = | ||
1033 | be16_to_cpu(SLI_CTNS_RSPN_ID); | ||
1034 | CtReq->un.rspn.PortId = be32_to_cpu(vport->fc_myDID); | ||
1035 | size = sizeof(CtReq->un.rspn.symbname); | ||
1036 | CtReq->un.rspn.len = | ||
1037 | lpfc_vport_symbolic_port_name(vport, | ||
1038 | CtReq->un.rspn.symbname, size); | ||
1039 | cmpl = lpfc_cmpl_ct_cmd_rspn_id; | ||
1040 | break; | ||
692 | case SLI_CTNS_RSNN_NN: | 1041 | case SLI_CTNS_RSNN_NN: |
693 | CtReq->CommandResponse.bits.CmdRsp = | 1042 | CtReq->CommandResponse.bits.CmdRsp = |
694 | be16_to_cpu(SLI_CTNS_RSNN_NN); | 1043 | be16_to_cpu(SLI_CTNS_RSNN_NN); |
695 | memcpy(CtReq->un.rsnn.wwnn, &phba->fc_nodename, | 1044 | memcpy(CtReq->un.rsnn.wwnn, &vport->fc_nodename, |
696 | sizeof (struct lpfc_name)); | 1045 | sizeof (struct lpfc_name)); |
697 | lpfc_get_hba_sym_node_name(phba, CtReq->un.rsnn.symbname); | 1046 | size = sizeof(CtReq->un.rsnn.symbname); |
698 | CtReq->un.rsnn.len = strlen(CtReq->un.rsnn.symbname); | 1047 | CtReq->un.rsnn.len = |
1048 | lpfc_vport_symbolic_node_name(vport, | ||
1049 | CtReq->un.rsnn.symbname, size); | ||
699 | cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; | 1050 | cmpl = lpfc_cmpl_ct_cmd_rsnn_nn; |
700 | break; | 1051 | break; |
1052 | case SLI_CTNS_RFF_ID: | ||
1053 | vport->fc_flag &= ~FC_RFF_NOT_SUPPORTED; | ||
1054 | CtReq->CommandResponse.bits.CmdRsp = | ||
1055 | be16_to_cpu(SLI_CTNS_RFF_ID); | ||
1056 | CtReq->un.rff.PortId = be32_to_cpu(vport->fc_myDID);; | ||
1057 | CtReq->un.rff.fbits = FC4_FEATURE_INIT; | ||
1058 | CtReq->un.rff.type_code = FC_FCP_DATA; | ||
1059 | cmpl = lpfc_cmpl_ct_cmd_rff_id; | ||
1060 | break; | ||
701 | } | 1061 | } |
702 | 1062 | ||
703 | if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, rsp_size)) | 1063 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, rsp_size, retry)) { |
704 | /* On success, The cmpl function will free the buffers */ | 1064 | /* On success, The cmpl function will free the buffers */ |
1065 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, | ||
1066 | "Issue CT cmd: cmd:x%x did:x%x", | ||
1067 | cmdcode, ndlp->nlp_DID, 0); | ||
705 | return 0; | 1068 | return 0; |
1069 | } | ||
706 | 1070 | ||
1071 | rc=6; | ||
707 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 1072 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
708 | ns_cmd_free_bmp: | 1073 | ns_cmd_free_bmp: |
709 | kfree(bmp); | 1074 | kfree(bmp); |
@@ -712,14 +1077,17 @@ ns_cmd_free_mpvirt: | |||
712 | ns_cmd_free_mp: | 1077 | ns_cmd_free_mp: |
713 | kfree(mp); | 1078 | kfree(mp); |
714 | ns_cmd_exit: | 1079 | ns_cmd_exit: |
1080 | lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY, | ||
1081 | "%d (%d):0266 Issue NameServer Req x%x err %d Data: x%x x%x\n", | ||
1082 | phba->brd_no, vport->vpi, cmdcode, rc, vport->fc_flag, | ||
1083 | vport->fc_rscn_id_cnt); | ||
715 | return 1; | 1084 | return 1; |
716 | } | 1085 | } |
717 | 1086 | ||
718 | static void | 1087 | static void |
719 | lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, | 1088 | lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
720 | struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) | 1089 | struct lpfc_iocbq * rspiocb) |
721 | { | 1090 | { |
722 | struct lpfc_dmabuf *bmp = cmdiocb->context3; | ||
723 | struct lpfc_dmabuf *inp = cmdiocb->context1; | 1091 | struct lpfc_dmabuf *inp = cmdiocb->context1; |
724 | struct lpfc_dmabuf *outp = cmdiocb->context2; | 1092 | struct lpfc_dmabuf *outp = cmdiocb->context2; |
725 | struct lpfc_sli_ct_request *CTrsp = outp->virt; | 1093 | struct lpfc_sli_ct_request *CTrsp = outp->virt; |
@@ -727,48 +1095,60 @@ lpfc_cmpl_ct_cmd_fdmi(struct lpfc_hba * phba, | |||
727 | struct lpfc_nodelist *ndlp; | 1095 | struct lpfc_nodelist *ndlp; |
728 | uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; | 1096 | uint16_t fdmi_cmd = CTcmd->CommandResponse.bits.CmdRsp; |
729 | uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; | 1097 | uint16_t fdmi_rsp = CTrsp->CommandResponse.bits.CmdRsp; |
1098 | struct lpfc_vport *vport = cmdiocb->vport; | ||
1099 | IOCB_t *irsp = &rspiocb->iocb; | ||
1100 | uint32_t latt; | ||
1101 | |||
1102 | latt = lpfc_els_chk_latt(vport); | ||
1103 | |||
1104 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_CT, | ||
1105 | "FDMI cmpl: status:x%x/x%x latt:%d", | ||
1106 | irsp->ulpStatus, irsp->un.ulpWord[4], latt); | ||
1107 | |||
1108 | if (latt || irsp->ulpStatus) { | ||
1109 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, | ||
1110 | "%d (%d):0229 FDMI cmd %04x failed, latt = %d " | ||
1111 | "ulpStatus: x%x, rid x%x\n", | ||
1112 | phba->brd_no, vport->vpi, | ||
1113 | be16_to_cpu(fdmi_cmd), latt, irsp->ulpStatus, | ||
1114 | irsp->un.ulpWord[4]); | ||
1115 | lpfc_ct_free_iocb(phba, cmdiocb); | ||
1116 | return; | ||
1117 | } | ||
730 | 1118 | ||
731 | ndlp = lpfc_findnode_did(phba, FDMI_DID); | 1119 | ndlp = lpfc_findnode_did(vport, FDMI_DID); |
732 | if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { | 1120 | if (fdmi_rsp == be16_to_cpu(SLI_CT_RESPONSE_FS_RJT)) { |
733 | /* FDMI rsp failed */ | 1121 | /* FDMI rsp failed */ |
734 | lpfc_printf_log(phba, | 1122 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
735 | KERN_INFO, | 1123 | "%d (%d):0220 FDMI rsp failed Data: x%x\n", |
736 | LOG_DISCOVERY, | 1124 | phba->brd_no, vport->vpi, |
737 | "%d:0220 FDMI rsp failed Data: x%x\n", | 1125 | be16_to_cpu(fdmi_cmd)); |
738 | phba->brd_no, | ||
739 | be16_to_cpu(fdmi_cmd)); | ||
740 | } | 1126 | } |
741 | 1127 | ||
742 | switch (be16_to_cpu(fdmi_cmd)) { | 1128 | switch (be16_to_cpu(fdmi_cmd)) { |
743 | case SLI_MGMT_RHBA: | 1129 | case SLI_MGMT_RHBA: |
744 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RPA); | 1130 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RPA); |
745 | break; | 1131 | break; |
746 | 1132 | ||
747 | case SLI_MGMT_RPA: | 1133 | case SLI_MGMT_RPA: |
748 | break; | 1134 | break; |
749 | 1135 | ||
750 | case SLI_MGMT_DHBA: | 1136 | case SLI_MGMT_DHBA: |
751 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DPRT); | 1137 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DPRT); |
752 | break; | 1138 | break; |
753 | 1139 | ||
754 | case SLI_MGMT_DPRT: | 1140 | case SLI_MGMT_DPRT: |
755 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_RHBA); | 1141 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_RHBA); |
756 | break; | 1142 | break; |
757 | } | 1143 | } |
758 | 1144 | lpfc_ct_free_iocb(phba, cmdiocb); | |
759 | lpfc_free_ct_rsp(phba, outp); | ||
760 | lpfc_mbuf_free(phba, inp->virt, inp->phys); | ||
761 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | ||
762 | kfree(inp); | ||
763 | kfree(bmp); | ||
764 | spin_lock_irq(phba->host->host_lock); | ||
765 | lpfc_sli_release_iocbq(phba, cmdiocb); | ||
766 | spin_unlock_irq(phba->host->host_lock); | ||
767 | return; | 1145 | return; |
768 | } | 1146 | } |
1147 | |||
769 | int | 1148 | int |
770 | lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | 1149 | lpfc_fdmi_cmd(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, int cmdcode) |
771 | { | 1150 | { |
1151 | struct lpfc_hba *phba = vport->phba; | ||
772 | struct lpfc_dmabuf *mp, *bmp; | 1152 | struct lpfc_dmabuf *mp, *bmp; |
773 | struct lpfc_sli_ct_request *CtReq; | 1153 | struct lpfc_sli_ct_request *CtReq; |
774 | struct ulp_bde64 *bpl; | 1154 | struct ulp_bde64 *bpl; |
@@ -805,12 +1185,10 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
805 | INIT_LIST_HEAD(&bmp->list); | 1185 | INIT_LIST_HEAD(&bmp->list); |
806 | 1186 | ||
807 | /* FDMI request */ | 1187 | /* FDMI request */ |
808 | lpfc_printf_log(phba, | 1188 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
809 | KERN_INFO, | 1189 | "%d (%d):0218 FDMI Request Data: x%x x%x x%x\n", |
810 | LOG_DISCOVERY, | 1190 | phba->brd_no, vport->vpi, vport->fc_flag, |
811 | "%d:0218 FDMI Request Data: x%x x%x x%x\n", | 1191 | vport->port_state, cmdcode); |
812 | phba->brd_no, | ||
813 | phba->fc_flag, phba->hba_state, cmdcode); | ||
814 | 1192 | ||
815 | CtReq = (struct lpfc_sli_ct_request *) mp->virt; | 1193 | CtReq = (struct lpfc_sli_ct_request *) mp->virt; |
816 | 1194 | ||
@@ -833,11 +1211,11 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
833 | be16_to_cpu(SLI_MGMT_RHBA); | 1211 | be16_to_cpu(SLI_MGMT_RHBA); |
834 | CtReq->CommandResponse.bits.Size = 0; | 1212 | CtReq->CommandResponse.bits.Size = 0; |
835 | rh = (REG_HBA *) & CtReq->un.PortID; | 1213 | rh = (REG_HBA *) & CtReq->un.PortID; |
836 | memcpy(&rh->hi.PortName, &phba->fc_sparam.portName, | 1214 | memcpy(&rh->hi.PortName, &vport->fc_sparam.portName, |
837 | sizeof (struct lpfc_name)); | 1215 | sizeof (struct lpfc_name)); |
838 | /* One entry (port) per adapter */ | 1216 | /* One entry (port) per adapter */ |
839 | rh->rpl.EntryCnt = be32_to_cpu(1); | 1217 | rh->rpl.EntryCnt = be32_to_cpu(1); |
840 | memcpy(&rh->rpl.pe, &phba->fc_sparam.portName, | 1218 | memcpy(&rh->rpl.pe, &vport->fc_sparam.portName, |
841 | sizeof (struct lpfc_name)); | 1219 | sizeof (struct lpfc_name)); |
842 | 1220 | ||
843 | /* point to the HBA attribute block */ | 1221 | /* point to the HBA attribute block */ |
@@ -853,7 +1231,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
853 | ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME); | 1231 | ae->ad.bits.AttrType = be16_to_cpu(NODE_NAME); |
854 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES | 1232 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES |
855 | + sizeof (struct lpfc_name)); | 1233 | + sizeof (struct lpfc_name)); |
856 | memcpy(&ae->un.NodeName, &phba->fc_sparam.nodeName, | 1234 | memcpy(&ae->un.NodeName, &vport->fc_sparam.nodeName, |
857 | sizeof (struct lpfc_name)); | 1235 | sizeof (struct lpfc_name)); |
858 | ab->EntryCnt++; | 1236 | ab->EntryCnt++; |
859 | size += FOURBYTES + sizeof (struct lpfc_name); | 1237 | size += FOURBYTES + sizeof (struct lpfc_name); |
@@ -991,7 +1369,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
991 | pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID; | 1369 | pab = (REG_PORT_ATTRIBUTE *) & CtReq->un.PortID; |
992 | size = sizeof (struct lpfc_name) + FOURBYTES; | 1370 | size = sizeof (struct lpfc_name) + FOURBYTES; |
993 | memcpy((uint8_t *) & pab->PortName, | 1371 | memcpy((uint8_t *) & pab->PortName, |
994 | (uint8_t *) & phba->fc_sparam.portName, | 1372 | (uint8_t *) & vport->fc_sparam.portName, |
995 | sizeof (struct lpfc_name)); | 1373 | sizeof (struct lpfc_name)); |
996 | pab->ab.EntryCnt = 0; | 1374 | pab->ab.EntryCnt = 0; |
997 | 1375 | ||
@@ -1053,7 +1431,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
1053 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); | 1431 | ae = (ATTRIBUTE_ENTRY *) ((uint8_t *) pab + size); |
1054 | ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE); | 1432 | ae->ad.bits.AttrType = be16_to_cpu(MAX_FRAME_SIZE); |
1055 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); | 1433 | ae->ad.bits.AttrLen = be16_to_cpu(FOURBYTES + 4); |
1056 | hsp = (struct serv_parm *) & phba->fc_sparam; | 1434 | hsp = (struct serv_parm *) & vport->fc_sparam; |
1057 | ae->un.MaxFrameSize = | 1435 | ae->un.MaxFrameSize = |
1058 | (((uint32_t) hsp->cmn. | 1436 | (((uint32_t) hsp->cmn. |
1059 | bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn. | 1437 | bbRcvSizeMsb) << 8) | (uint32_t) hsp->cmn. |
@@ -1097,7 +1475,7 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
1097 | CtReq->CommandResponse.bits.Size = 0; | 1475 | CtReq->CommandResponse.bits.Size = 0; |
1098 | pe = (PORT_ENTRY *) & CtReq->un.PortID; | 1476 | pe = (PORT_ENTRY *) & CtReq->un.PortID; |
1099 | memcpy((uint8_t *) & pe->PortName, | 1477 | memcpy((uint8_t *) & pe->PortName, |
1100 | (uint8_t *) & phba->fc_sparam.portName, | 1478 | (uint8_t *) & vport->fc_sparam.portName, |
1101 | sizeof (struct lpfc_name)); | 1479 | sizeof (struct lpfc_name)); |
1102 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); | 1480 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); |
1103 | break; | 1481 | break; |
@@ -1107,22 +1485,22 @@ lpfc_fdmi_cmd(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, int cmdcode) | |||
1107 | CtReq->CommandResponse.bits.Size = 0; | 1485 | CtReq->CommandResponse.bits.Size = 0; |
1108 | pe = (PORT_ENTRY *) & CtReq->un.PortID; | 1486 | pe = (PORT_ENTRY *) & CtReq->un.PortID; |
1109 | memcpy((uint8_t *) & pe->PortName, | 1487 | memcpy((uint8_t *) & pe->PortName, |
1110 | (uint8_t *) & phba->fc_sparam.portName, | 1488 | (uint8_t *) & vport->fc_sparam.portName, |
1111 | sizeof (struct lpfc_name)); | 1489 | sizeof (struct lpfc_name)); |
1112 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); | 1490 | size = GID_REQUEST_SZ - 4 + sizeof (struct lpfc_name); |
1113 | break; | 1491 | break; |
1114 | } | 1492 | } |
1115 | 1493 | ||
1116 | bpl = (struct ulp_bde64 *) bmp->virt; | 1494 | bpl = (struct ulp_bde64 *) bmp->virt; |
1117 | bpl->addrHigh = le32_to_cpu( putPaddrHigh(mp->phys) ); | 1495 | bpl->addrHigh = le32_to_cpu(putPaddrHigh(mp->phys) ); |
1118 | bpl->addrLow = le32_to_cpu( putPaddrLow(mp->phys) ); | 1496 | bpl->addrLow = le32_to_cpu(putPaddrLow(mp->phys) ); |
1119 | bpl->tus.f.bdeFlags = 0; | 1497 | bpl->tus.f.bdeFlags = 0; |
1120 | bpl->tus.f.bdeSize = size; | 1498 | bpl->tus.f.bdeSize = size; |
1121 | bpl->tus.w = le32_to_cpu(bpl->tus.w); | 1499 | bpl->tus.w = le32_to_cpu(bpl->tus.w); |
1122 | 1500 | ||
1123 | cmpl = lpfc_cmpl_ct_cmd_fdmi; | 1501 | cmpl = lpfc_cmpl_ct_cmd_fdmi; |
1124 | 1502 | ||
1125 | if (!lpfc_ct_cmd(phba, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP)) | 1503 | if (!lpfc_ct_cmd(vport, mp, bmp, ndlp, cmpl, FC_MAX_NS_RSP, 0)) |
1126 | return 0; | 1504 | return 0; |
1127 | 1505 | ||
1128 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); | 1506 | lpfc_mbuf_free(phba, bmp->virt, bmp->phys); |
@@ -1134,49 +1512,50 @@ fdmi_cmd_free_mp: | |||
1134 | kfree(mp); | 1512 | kfree(mp); |
1135 | fdmi_cmd_exit: | 1513 | fdmi_cmd_exit: |
1136 | /* Issue FDMI request failed */ | 1514 | /* Issue FDMI request failed */ |
1137 | lpfc_printf_log(phba, | 1515 | lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY, |
1138 | KERN_INFO, | 1516 | "%d (%d):0244 Issue FDMI request failed Data: x%x\n", |
1139 | LOG_DISCOVERY, | 1517 | phba->brd_no, vport->vpi, cmdcode); |
1140 | "%d:0244 Issue FDMI request failed Data: x%x\n", | ||
1141 | phba->brd_no, | ||
1142 | cmdcode); | ||
1143 | return 1; | 1518 | return 1; |
1144 | } | 1519 | } |
1145 | 1520 | ||
1146 | void | 1521 | void |
1147 | lpfc_fdmi_tmo(unsigned long ptr) | 1522 | lpfc_fdmi_tmo(unsigned long ptr) |
1148 | { | 1523 | { |
1149 | struct lpfc_hba *phba = (struct lpfc_hba *)ptr; | 1524 | struct lpfc_vport *vport = (struct lpfc_vport *)ptr; |
1525 | struct lpfc_hba *phba = vport->phba; | ||
1150 | unsigned long iflag; | 1526 | unsigned long iflag; |
1151 | 1527 | ||
1152 | spin_lock_irqsave(phba->host->host_lock, iflag); | 1528 | spin_lock_irqsave(&vport->work_port_lock, iflag); |
1153 | if (!(phba->work_hba_events & WORKER_FDMI_TMO)) { | 1529 | if (!(vport->work_port_events & WORKER_FDMI_TMO)) { |
1154 | phba->work_hba_events |= WORKER_FDMI_TMO; | 1530 | vport->work_port_events |= WORKER_FDMI_TMO; |
1531 | spin_unlock_irqrestore(&vport->work_port_lock, iflag); | ||
1532 | |||
1533 | spin_lock_irqsave(&phba->hbalock, iflag); | ||
1155 | if (phba->work_wait) | 1534 | if (phba->work_wait) |
1156 | wake_up(phba->work_wait); | 1535 | lpfc_worker_wake_up(phba); |
1536 | spin_unlock_irqrestore(&phba->hbalock, iflag); | ||
1157 | } | 1537 | } |
1158 | spin_unlock_irqrestore(phba->host->host_lock,iflag); | 1538 | else |
1539 | spin_unlock_irqrestore(&vport->work_port_lock, iflag); | ||
1159 | } | 1540 | } |
1160 | 1541 | ||
1161 | void | 1542 | void |
1162 | lpfc_fdmi_tmo_handler(struct lpfc_hba *phba) | 1543 | lpfc_fdmi_timeout_handler(struct lpfc_vport *vport) |
1163 | { | 1544 | { |
1164 | struct lpfc_nodelist *ndlp; | 1545 | struct lpfc_nodelist *ndlp; |
1165 | 1546 | ||
1166 | ndlp = lpfc_findnode_did(phba, FDMI_DID); | 1547 | ndlp = lpfc_findnode_did(vport, FDMI_DID); |
1167 | if (ndlp) { | 1548 | if (ndlp) { |
1168 | if (init_utsname()->nodename[0] != '\0') { | 1549 | if (init_utsname()->nodename[0] != '\0') |
1169 | lpfc_fdmi_cmd(phba, ndlp, SLI_MGMT_DHBA); | 1550 | lpfc_fdmi_cmd(vport, ndlp, SLI_MGMT_DHBA); |
1170 | } else { | 1551 | else |
1171 | mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); | 1552 | mod_timer(&vport->fc_fdmitmo, jiffies + HZ * 60); |
1172 | } | ||
1173 | } | 1553 | } |
1174 | return; | 1554 | return; |
1175 | } | 1555 | } |
1176 | 1556 | ||
1177 | |||
1178 | void | 1557 | void |
1179 | lpfc_decode_firmware_rev(struct lpfc_hba * phba, char *fwrevision, int flag) | 1558 | lpfc_decode_firmware_rev(struct lpfc_hba *phba, char *fwrevision, int flag) |
1180 | { | 1559 | { |
1181 | struct lpfc_sli *psli = &phba->sli; | 1560 | struct lpfc_sli *psli = &phba->sli; |
1182 | lpfc_vpd_t *vp = &phba->vpd; | 1561 | lpfc_vpd_t *vp = &phba->vpd; |