diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 988 |
1 files changed, 493 insertions, 495 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index b309841e3846..e6452b88d958 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c | |||
@@ -39,16 +39,16 @@ | |||
39 | 39 | ||
40 | /* Called to verify a rcv'ed ADISC was intended for us. */ | 40 | /* Called to verify a rcv'ed ADISC was intended for us. */ |
41 | static int | 41 | static int |
42 | lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 42 | lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
43 | struct lpfc_name * nn, struct lpfc_name * pn) | 43 | struct lpfc_name *nn, struct lpfc_name *pn) |
44 | { | 44 | { |
45 | /* Compare the ADISC rsp WWNN / WWPN matches our internal node | 45 | /* Compare the ADISC rsp WWNN / WWPN matches our internal node |
46 | * table entry for that node. | 46 | * table entry for that node. |
47 | */ | 47 | */ |
48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)) != 0) | 48 | if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name))) |
49 | return 0; | 49 | return 0; |
50 | 50 | ||
51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)) != 0) | 51 | if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name))) |
52 | return 0; | 52 | return 0; |
53 | 53 | ||
54 | /* we match, return success */ | 54 | /* we match, return success */ |
@@ -56,11 +56,10 @@ lpfc_check_adisc(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
56 | } | 56 | } |
57 | 57 | ||
58 | int | 58 | int |
59 | lpfc_check_sparm(struct lpfc_hba * phba, | 59 | lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
60 | struct lpfc_nodelist * ndlp, struct serv_parm * sp, | 60 | struct serv_parm * sp, uint32_t class) |
61 | uint32_t class) | ||
62 | { | 61 | { |
63 | volatile struct serv_parm *hsp = &phba->fc_sparam; | 62 | volatile struct serv_parm *hsp = &vport->fc_sparam; |
64 | uint16_t hsp_value, ssp_value = 0; | 63 | uint16_t hsp_value, ssp_value = 0; |
65 | 64 | ||
66 | /* | 65 | /* |
@@ -128,8 +127,7 @@ lpfc_check_sparm(struct lpfc_hba * phba, | |||
128 | } | 127 | } |
129 | 128 | ||
130 | static void * | 129 | static void * |
131 | lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | 130 | lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
132 | struct lpfc_iocbq *cmdiocb, | ||
133 | struct lpfc_iocbq *rspiocb) | 131 | struct lpfc_iocbq *rspiocb) |
134 | { | 132 | { |
135 | struct lpfc_dmabuf *pcmd, *prsp; | 133 | struct lpfc_dmabuf *pcmd, *prsp; |
@@ -168,11 +166,11 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba * phba, | |||
168 | * routine effectively results in a "software abort". | 166 | * routine effectively results in a "software abort". |
169 | */ | 167 | */ |
170 | int | 168 | int |
171 | lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | 169 | lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
172 | { | 170 | { |
173 | LIST_HEAD(completions); | 171 | LIST_HEAD(completions); |
174 | struct lpfc_sli *psli; | 172 | struct lpfc_sli *psli = &phba->sli; |
175 | struct lpfc_sli_ring *pring; | 173 | struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; |
176 | struct lpfc_iocbq *iocb, *next_iocb; | 174 | struct lpfc_iocbq *iocb, *next_iocb; |
177 | IOCB_t *cmd; | 175 | IOCB_t *cmd; |
178 | 176 | ||
@@ -183,11 +181,8 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
183 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, | 181 | phba->brd_no, ndlp->nlp_DID, ndlp->nlp_flag, |
184 | ndlp->nlp_state, ndlp->nlp_rpi); | 182 | ndlp->nlp_state, ndlp->nlp_rpi); |
185 | 183 | ||
186 | psli = &phba->sli; | ||
187 | pring = &psli->ring[LPFC_ELS_RING]; | ||
188 | |||
189 | /* First check the txq */ | 184 | /* First check the txq */ |
190 | spin_lock_irq(phba->host->host_lock); | 185 | spin_lock_irq(&phba->hbalock); |
191 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { | 186 | list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) { |
192 | /* Check to see if iocb matches the nport we are looking | 187 | /* Check to see if iocb matches the nport we are looking |
193 | for */ | 188 | for */ |
@@ -206,32 +201,34 @@ lpfc_els_abort(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) | |||
206 | if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) | 201 | if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) |
207 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); | 202 | lpfc_sli_issue_abort_iotag(phba, pring, iocb); |
208 | } | 203 | } |
209 | spin_unlock_irq(phba->host->host_lock); | 204 | spin_unlock_irq(&phba->hbalock); |
210 | 205 | ||
211 | while (!list_empty(&completions)) { | 206 | while (!list_empty(&completions)) { |
212 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); | 207 | iocb = list_get_first(&completions, struct lpfc_iocbq, list); |
213 | cmd = &iocb->iocb; | 208 | cmd = &iocb->iocb; |
214 | list_del(&iocb->list); | 209 | list_del(&iocb->list); |
215 | 210 | ||
216 | if (iocb->iocb_cmpl) { | 211 | if (!iocb->iocb_cmpl) |
212 | lpfc_sli_release_iocbq(phba, iocb); | ||
213 | else { | ||
217 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; | 214 | cmd->ulpStatus = IOSTAT_LOCAL_REJECT; |
218 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; | 215 | cmd->un.ulpWord[4] = IOERR_SLI_ABORTED; |
219 | (iocb->iocb_cmpl) (phba, iocb, iocb); | 216 | (iocb->iocb_cmpl) (phba, iocb, iocb); |
220 | } else | 217 | } |
221 | lpfc_sli_release_iocbq(phba, iocb); | ||
222 | } | 218 | } |
223 | 219 | ||
224 | /* If we are delaying issuing an ELS command, cancel it */ | 220 | /* If we are delaying issuing an ELS command, cancel it */ |
225 | if (ndlp->nlp_flag & NLP_DELAY_TMO) | 221 | if (ndlp->nlp_flag & NLP_DELAY_TMO) |
226 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 222 | lpfc_cancel_retry_delay_tmo(phba->pport, ndlp); |
227 | return 0; | 223 | return 0; |
228 | } | 224 | } |
229 | 225 | ||
230 | static int | 226 | static int |
231 | lpfc_rcv_plogi(struct lpfc_hba * phba, | 227 | lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
232 | struct lpfc_nodelist * ndlp, | ||
233 | struct lpfc_iocbq *cmdiocb) | 228 | struct lpfc_iocbq *cmdiocb) |
234 | { | 229 | { |
230 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
231 | struct lpfc_hba *phba = vport->phba; | ||
235 | struct lpfc_dmabuf *pcmd; | 232 | struct lpfc_dmabuf *pcmd; |
236 | uint32_t *lp; | 233 | uint32_t *lp; |
237 | IOCB_t *icmd; | 234 | IOCB_t *icmd; |
@@ -241,14 +238,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
241 | int rc; | 238 | int rc; |
242 | 239 | ||
243 | memset(&stat, 0, sizeof (struct ls_rjt)); | 240 | memset(&stat, 0, sizeof (struct ls_rjt)); |
244 | if (phba->hba_state <= LPFC_FLOGI) { | 241 | if (vport->port_state <= LPFC_FLOGI) { |
245 | /* Before responding to PLOGI, check for pt2pt mode. | 242 | /* Before responding to PLOGI, check for pt2pt mode. |
246 | * If we are pt2pt, with an outstanding FLOGI, abort | 243 | * If we are pt2pt, with an outstanding FLOGI, abort |
247 | * the FLOGI and resend it first. | 244 | * the FLOGI and resend it first. |
248 | */ | 245 | */ |
249 | if (phba->fc_flag & FC_PT2PT) { | 246 | if (vport->fc_flag & FC_PT2PT) { |
250 | lpfc_els_abort_flogi(phba); | 247 | lpfc_els_abort_flogi(phba); |
251 | if (!(phba->fc_flag & FC_PT2PT_PLOGI)) { | 248 | if (!(vport->fc_flag & FC_PT2PT_PLOGI)) { |
252 | /* If the other side is supposed to initiate | 249 | /* If the other side is supposed to initiate |
253 | * the PLOGI anyway, just ACC it now and | 250 | * the PLOGI anyway, just ACC it now and |
254 | * move on with discovery. | 251 | * move on with discovery. |
@@ -257,14 +254,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
257 | phba->fc_ratov = FF_DEF_RATOV; | 254 | phba->fc_ratov = FF_DEF_RATOV; |
258 | /* Start discovery - this should just do | 255 | /* Start discovery - this should just do |
259 | CLEAR_LA */ | 256 | CLEAR_LA */ |
260 | lpfc_disc_start(phba); | 257 | lpfc_disc_start(vport); |
261 | } else { | 258 | } else { |
262 | lpfc_initial_flogi(phba); | 259 | lpfc_initial_flogi(vport); |
263 | } | 260 | } |
264 | } else { | 261 | } else { |
265 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; | 262 | stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY; |
266 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 263 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
267 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, | 264 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, |
268 | ndlp); | 265 | ndlp); |
269 | return 0; | 266 | return 0; |
270 | } | 267 | } |
@@ -272,11 +269,11 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
272 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 269 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
273 | lp = (uint32_t *) pcmd->virt; | 270 | lp = (uint32_t *) pcmd->virt; |
274 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 271 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
275 | if ((lpfc_check_sparm(phba, ndlp, sp, CLASS3) == 0)) { | 272 | if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3) == 0)) { |
276 | /* Reject this request because invalid parameters */ | 273 | /* Reject this request because invalid parameters */ |
277 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 274 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
278 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 275 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
279 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 276 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
280 | return 0; | 277 | return 0; |
281 | } | 278 | } |
282 | icmd = &cmdiocb->iocb; | 279 | icmd = &cmdiocb->iocb; |
@@ -290,12 +287,12 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
290 | ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, | 287 | ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag, |
291 | ndlp->nlp_rpi); | 288 | ndlp->nlp_rpi); |
292 | 289 | ||
293 | if ((phba->cfg_fcp_class == 2) && | 290 | if (phba->cfg_fcp_class == 2 && sp->cls2.classValid) { |
294 | (sp->cls2.classValid)) { | ||
295 | ndlp->nlp_fcp_info |= CLASS2; | 291 | ndlp->nlp_fcp_info |= CLASS2; |
296 | } else { | 292 | } else { |
297 | ndlp->nlp_fcp_info |= CLASS3; | 293 | ndlp->nlp_fcp_info |= CLASS3; |
298 | } | 294 | } |
295 | |||
299 | ndlp->nlp_class_sup = 0; | 296 | ndlp->nlp_class_sup = 0; |
300 | if (sp->cls1.classValid) | 297 | if (sp->cls1.classValid) |
301 | ndlp->nlp_class_sup |= FC_COS_CLASS1; | 298 | ndlp->nlp_class_sup |= FC_COS_CLASS1; |
@@ -317,14 +314,14 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
317 | case NLP_STE_PRLI_ISSUE: | 314 | case NLP_STE_PRLI_ISSUE: |
318 | case NLP_STE_UNMAPPED_NODE: | 315 | case NLP_STE_UNMAPPED_NODE: |
319 | case NLP_STE_MAPPED_NODE: | 316 | case NLP_STE_MAPPED_NODE: |
320 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); | 317 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL, 0); |
321 | return 1; | 318 | return 1; |
322 | } | 319 | } |
323 | 320 | ||
324 | if ((phba->fc_flag & FC_PT2PT) | 321 | if ((vport->fc_flag & FC_PT2PT) |
325 | && !(phba->fc_flag & FC_PT2PT_PLOGI)) { | 322 | && !(vport->fc_flag & FC_PT2PT_PLOGI)) { |
326 | /* rcv'ed PLOGI decides what our NPortId will be */ | 323 | /* rcv'ed PLOGI decides what our NPortId will be */ |
327 | phba->fc_myDID = icmd->un.rcvels.parmRo; | 324 | vport->fc_myDID = icmd->un.rcvels.parmRo; |
328 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 325 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
329 | if (mbox == NULL) | 326 | if (mbox == NULL) |
330 | goto out; | 327 | goto out; |
@@ -337,15 +334,16 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
337 | goto out; | 334 | goto out; |
338 | } | 335 | } |
339 | 336 | ||
340 | lpfc_can_disctmo(phba); | 337 | lpfc_can_disctmo(vport); |
341 | } | 338 | } |
342 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); | 339 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
343 | if (mbox == NULL) | 340 | if (!mbox) |
344 | goto out; | 341 | goto out; |
345 | 342 | ||
346 | if (lpfc_reg_login(phba, icmd->un.rcvels.remoteID, | 343 | rc = lpfc_reg_login(phba, icmd->un.rcvels.remoteID, (uint8_t *) sp, |
347 | (uint8_t *) sp, mbox, 0)) { | 344 | mbox, 0); |
348 | mempool_free( mbox, phba->mbox_mem_pool); | 345 | if (rc) { |
346 | mempool_free(mbox, phba->mbox_mem_pool); | ||
349 | goto out; | 347 | goto out; |
350 | } | 348 | } |
351 | 349 | ||
@@ -357,7 +355,10 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
357 | * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox | 355 | * mbox->context2 = lpfc_nlp_get(ndlp) deferred until mailbox |
358 | * command issued in lpfc_cmpl_els_acc(). | 356 | * command issued in lpfc_cmpl_els_acc(). |
359 | */ | 357 | */ |
358 | mbox->vport = vport; | ||
359 | spin_lock_irq(shost->host_lock); | ||
360 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); | 360 | ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI); |
361 | spin_unlock_irq(shost->host_lock); | ||
361 | 362 | ||
362 | /* | 363 | /* |
363 | * If there is an outstanding PLOGI issued, abort it before | 364 | * If there is an outstanding PLOGI issued, abort it before |
@@ -373,24 +374,24 @@ lpfc_rcv_plogi(struct lpfc_hba * phba, | |||
373 | lpfc_els_abort(phba, ndlp); | 374 | lpfc_els_abort(phba, ndlp); |
374 | } | 375 | } |
375 | 376 | ||
376 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); | 377 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox, 0); |
377 | return 1; | 378 | return 1; |
378 | 379 | ||
379 | out: | 380 | out: |
380 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 381 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
381 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; | 382 | stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE; |
382 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 383 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
383 | return 0; | 384 | return 0; |
384 | } | 385 | } |
385 | 386 | ||
386 | static int | 387 | static int |
387 | lpfc_rcv_padisc(struct lpfc_hba * phba, | 388 | lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
388 | struct lpfc_nodelist * ndlp, | ||
389 | struct lpfc_iocbq *cmdiocb) | 389 | struct lpfc_iocbq *cmdiocb) |
390 | { | 390 | { |
391 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
391 | struct lpfc_dmabuf *pcmd; | 392 | struct lpfc_dmabuf *pcmd; |
392 | struct serv_parm *sp; | 393 | struct serv_parm *sp; |
393 | struct lpfc_name *pnn, *ppn; | 394 | struct lpfc_name *pnn, *ppn; |
394 | struct ls_rjt stat; | 395 | struct ls_rjt stat; |
395 | ADISC *ap; | 396 | ADISC *ap; |
396 | IOCB_t *icmd; | 397 | IOCB_t *icmd; |
@@ -412,12 +413,11 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
412 | } | 413 | } |
413 | 414 | ||
414 | icmd = &cmdiocb->iocb; | 415 | icmd = &cmdiocb->iocb; |
415 | if ((icmd->ulpStatus == 0) && | 416 | if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) { |
416 | (lpfc_check_adisc(phba, ndlp, pnn, ppn))) { | ||
417 | if (cmd == ELS_CMD_ADISC) { | 417 | if (cmd == ELS_CMD_ADISC) { |
418 | lpfc_els_rsp_adisc_acc(phba, cmdiocb, ndlp); | 418 | lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp); |
419 | } else { | 419 | } else { |
420 | lpfc_els_rsp_acc(phba, ELS_CMD_PLOGI, cmdiocb, ndlp, | 420 | lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, |
421 | NULL, 0); | 421 | NULL, 0); |
422 | } | 422 | } |
423 | return 1; | 423 | return 1; |
@@ -427,55 +427,57 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, | |||
427 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 427 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
428 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 428 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
429 | stat.un.b.vendorUnique = 0; | 429 | stat.un.b.vendorUnique = 0; |
430 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 430 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
431 | 431 | ||
432 | /* 1 sec timeout */ | 432 | /* 1 sec timeout */ |
433 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 433 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
434 | 434 | ||
435 | spin_lock_irq(phba->host->host_lock); | 435 | spin_lock_irq(shost->host_lock); |
436 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 436 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
437 | spin_unlock_irq(phba->host->host_lock); | 437 | spin_unlock_irq(shost->host_lock); |
438 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 438 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
439 | ndlp->nlp_prev_state = ndlp->nlp_state; | 439 | ndlp->nlp_prev_state = ndlp->nlp_state; |
440 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 440 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
441 | return 0; | 441 | return 0; |
442 | } | 442 | } |
443 | 443 | ||
444 | static int | 444 | static int |
445 | lpfc_rcv_logo(struct lpfc_hba * phba, | 445 | lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
446 | struct lpfc_nodelist * ndlp, | 446 | struct lpfc_iocbq *cmdiocb, uint32_t els_cmd) |
447 | struct lpfc_iocbq *cmdiocb, | ||
448 | uint32_t els_cmd) | ||
449 | { | 447 | { |
450 | /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */ | 448 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
449 | |||
450 | /* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */ | ||
451 | /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary | 451 | /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary |
452 | * PLOGIs during LOGO storms from a device. | 452 | * PLOGIs during LOGO storms from a device. |
453 | */ | 453 | */ |
454 | spin_lock_irq(shost->host_lock); | ||
454 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 455 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
456 | spin_unlock_irq(shost->host_lock); | ||
455 | if (els_cmd == ELS_CMD_PRLO) | 457 | if (els_cmd == ELS_CMD_PRLO) |
456 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | 458 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
457 | else | 459 | else |
458 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 460 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
459 | 461 | ||
460 | if (!(ndlp->nlp_type & NLP_FABRIC) || | 462 | if (!(ndlp->nlp_type & NLP_FABRIC) || |
461 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { | 463 | (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) { |
462 | /* Only try to re-login if this is NOT a Fabric Node */ | 464 | /* Only try to re-login if this is NOT a Fabric Node */ |
463 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 465 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
464 | spin_lock_irq(phba->host->host_lock); | 466 | spin_lock_irq(shost->host_lock); |
465 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 467 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
466 | spin_unlock_irq(phba->host->host_lock); | 468 | spin_unlock_irq(shost->host_lock); |
467 | 469 | ||
468 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 470 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
469 | ndlp->nlp_prev_state = ndlp->nlp_state; | 471 | ndlp->nlp_prev_state = ndlp->nlp_state; |
470 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 472 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
471 | } else { | 473 | } else { |
472 | ndlp->nlp_prev_state = ndlp->nlp_state; | 474 | ndlp->nlp_prev_state = ndlp->nlp_state; |
473 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 475 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
474 | } | 476 | } |
475 | 477 | ||
476 | spin_lock_irq(phba->host->host_lock); | 478 | spin_lock_irq(shost->host_lock); |
477 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 479 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
478 | spin_unlock_irq(phba->host->host_lock); | 480 | spin_unlock_irq(shost->host_lock); |
479 | /* The driver has to wait until the ACC completes before it continues | 481 | /* The driver has to wait until the ACC completes before it continues |
480 | * processing the LOGO. The action will resume in | 482 | * processing the LOGO. The action will resume in |
481 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an | 483 | * lpfc_cmpl_els_logo_acc routine. Since part of processing includes an |
@@ -485,9 +487,8 @@ lpfc_rcv_logo(struct lpfc_hba * phba, | |||
485 | } | 487 | } |
486 | 488 | ||
487 | static void | 489 | static void |
488 | lpfc_rcv_prli(struct lpfc_hba * phba, | 490 | lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
489 | struct lpfc_nodelist * ndlp, | 491 | struct lpfc_iocbq *cmdiocb) |
490 | struct lpfc_iocbq *cmdiocb) | ||
491 | { | 492 | { |
492 | struct lpfc_dmabuf *pcmd; | 493 | struct lpfc_dmabuf *pcmd; |
493 | uint32_t *lp; | 494 | uint32_t *lp; |
@@ -522,31 +523,33 @@ lpfc_rcv_prli(struct lpfc_hba * phba, | |||
522 | } | 523 | } |
523 | 524 | ||
524 | static uint32_t | 525 | static uint32_t |
525 | lpfc_disc_set_adisc(struct lpfc_hba * phba, | 526 | lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
526 | struct lpfc_nodelist * ndlp) | ||
527 | { | 527 | { |
528 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
529 | struct lpfc_hba *phba = vport->phba; | ||
530 | |||
528 | /* Check config parameter use-adisc or FCP-2 */ | 531 | /* Check config parameter use-adisc or FCP-2 */ |
529 | if ((phba->cfg_use_adisc == 0) && | 532 | if (phba->cfg_use_adisc == 0 && |
530 | !(phba->fc_flag & FC_RSCN_MODE)) { | 533 | (vport->fc_flag & FC_RSCN_MODE) == 0 && |
531 | if (!(ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE)) | 534 | (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) == 0) |
532 | return 0; | 535 | return 0; |
533 | } | 536 | |
534 | spin_lock_irq(phba->host->host_lock); | 537 | spin_lock_irq(shost->host_lock); |
535 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 538 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
536 | spin_unlock_irq(phba->host->host_lock); | 539 | spin_unlock_irq(shost->host_lock); |
537 | return 1; | 540 | return 1; |
538 | } | 541 | } |
539 | 542 | ||
540 | static uint32_t | 543 | static uint32_t |
541 | lpfc_disc_illegal(struct lpfc_hba * phba, | 544 | lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
542 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 545 | void *arg, uint32_t evt) |
543 | { | 546 | { |
544 | lpfc_printf_log(phba, | 547 | lpfc_printf_log(vport->phba, |
545 | KERN_ERR, | 548 | KERN_ERR, |
546 | LOG_DISCOVERY, | 549 | LOG_DISCOVERY, |
547 | "%d:0253 Illegal State Transition: node x%x event x%x, " | 550 | "%d:0253 Illegal State Transition: node x%x event x%x, " |
548 | "state x%x Data: x%x x%x\n", | 551 | "state x%x Data: x%x x%x\n", |
549 | phba->brd_no, | 552 | vport->phba->brd_no, |
550 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, | 553 | ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi, |
551 | ndlp->nlp_flag); | 554 | ndlp->nlp_flag); |
552 | return ndlp->nlp_state; | 555 | return ndlp->nlp_state; |
@@ -555,86 +558,82 @@ lpfc_disc_illegal(struct lpfc_hba * phba, | |||
555 | /* Start of Discovery State Machine routines */ | 558 | /* Start of Discovery State Machine routines */ |
556 | 559 | ||
557 | static uint32_t | 560 | static uint32_t |
558 | lpfc_rcv_plogi_unused_node(struct lpfc_hba * phba, | 561 | lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
559 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 562 | void *arg, uint32_t evt) |
560 | { | 563 | { |
561 | struct lpfc_iocbq *cmdiocb; | 564 | struct lpfc_iocbq *cmdiocb; |
562 | 565 | ||
563 | cmdiocb = (struct lpfc_iocbq *) arg; | 566 | cmdiocb = (struct lpfc_iocbq *) arg; |
564 | 567 | ||
565 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 568 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { |
566 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | 569 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; |
567 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 570 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
568 | return ndlp->nlp_state; | 571 | return ndlp->nlp_state; |
569 | } | 572 | } |
570 | lpfc_drop_node(phba, ndlp); | 573 | lpfc_drop_node(vport, ndlp); |
571 | return NLP_STE_FREED_NODE; | 574 | return NLP_STE_FREED_NODE; |
572 | } | 575 | } |
573 | 576 | ||
574 | static uint32_t | 577 | static uint32_t |
575 | lpfc_rcv_els_unused_node(struct lpfc_hba * phba, | 578 | lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
576 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 579 | void *arg, uint32_t evt) |
577 | { | 580 | { |
578 | lpfc_issue_els_logo(phba, ndlp, 0); | 581 | lpfc_issue_els_logo(vport, ndlp, 0); |
579 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 582 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
580 | return ndlp->nlp_state; | 583 | return ndlp->nlp_state; |
581 | } | 584 | } |
582 | 585 | ||
583 | static uint32_t | 586 | static uint32_t |
584 | lpfc_rcv_logo_unused_node(struct lpfc_hba * phba, | 587 | lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
585 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 588 | void *arg, uint32_t evt) |
586 | { | 589 | { |
587 | struct lpfc_iocbq *cmdiocb; | 590 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
588 | 591 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | |
589 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
590 | 592 | ||
591 | spin_lock_irq(phba->host->host_lock); | 593 | spin_lock_irq(shost->host_lock); |
592 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 594 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
593 | spin_unlock_irq(phba->host->host_lock); | 595 | spin_unlock_irq(shost->host_lock); |
594 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 596 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
595 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 597 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
596 | 598 | ||
597 | return ndlp->nlp_state; | 599 | return ndlp->nlp_state; |
598 | } | 600 | } |
599 | 601 | ||
600 | static uint32_t | 602 | static uint32_t |
601 | lpfc_cmpl_logo_unused_node(struct lpfc_hba * phba, | 603 | lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
602 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 604 | void *arg, uint32_t evt) |
603 | { | 605 | { |
604 | lpfc_drop_node(phba, ndlp); | 606 | lpfc_drop_node(vport, ndlp); |
605 | return NLP_STE_FREED_NODE; | 607 | return NLP_STE_FREED_NODE; |
606 | } | 608 | } |
607 | 609 | ||
608 | static uint32_t | 610 | static uint32_t |
609 | lpfc_device_rm_unused_node(struct lpfc_hba * phba, | 611 | lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
610 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 612 | void *arg, uint32_t evt) |
611 | { | 613 | { |
612 | lpfc_drop_node(phba, ndlp); | 614 | lpfc_drop_node(vport, ndlp); |
613 | return NLP_STE_FREED_NODE; | 615 | return NLP_STE_FREED_NODE; |
614 | } | 616 | } |
615 | 617 | ||
616 | static uint32_t | 618 | static uint32_t |
617 | lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | 619 | lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
618 | void *arg, uint32_t evt) | 620 | void *arg, uint32_t evt) |
619 | { | 621 | { |
622 | struct lpfc_hba *phba = vport->phba; | ||
620 | struct lpfc_iocbq *cmdiocb = arg; | 623 | struct lpfc_iocbq *cmdiocb = arg; |
621 | struct lpfc_dmabuf *pcmd; | 624 | struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
622 | struct serv_parm *sp; | 625 | uint32_t *lp = (uint32_t *) pcmd->virt; |
623 | uint32_t *lp; | 626 | struct serv_parm *sp = (struct serv_parm *) (lp + 1); |
624 | struct ls_rjt stat; | 627 | struct ls_rjt stat; |
625 | int port_cmp; | 628 | int port_cmp; |
626 | 629 | ||
627 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | ||
628 | lp = (uint32_t *) pcmd->virt; | ||
629 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | ||
630 | |||
631 | memset(&stat, 0, sizeof (struct ls_rjt)); | 630 | memset(&stat, 0, sizeof (struct ls_rjt)); |
632 | 631 | ||
633 | /* For a PLOGI, we only accept if our portname is less | 632 | /* For a PLOGI, we only accept if our portname is less |
634 | * than the remote portname. | 633 | * than the remote portname. |
635 | */ | 634 | */ |
636 | phba->fc_stat.elsLogiCol++; | 635 | phba->fc_stat.elsLogiCol++; |
637 | port_cmp = memcmp(&phba->fc_portname, &sp->portName, | 636 | port_cmp = memcmp(&vport->fc_portname, &sp->portName, |
638 | sizeof (struct lpfc_name)); | 637 | sizeof (struct lpfc_name)); |
639 | 638 | ||
640 | if (port_cmp >= 0) { | 639 | if (port_cmp >= 0) { |
@@ -642,64 +641,64 @@ lpfc_rcv_plogi_plogi_issue(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, | |||
642 | ours */ | 641 | ours */ |
643 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 642 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
644 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; | 643 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; |
645 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 644 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
646 | } else { | 645 | } else { |
647 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 646 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
648 | } /* if our portname was less */ | 647 | } /* If our portname was less */ |
649 | 648 | ||
650 | return ndlp->nlp_state; | 649 | return ndlp->nlp_state; |
651 | } | 650 | } |
652 | 651 | ||
653 | static uint32_t | 652 | static uint32_t |
654 | lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, | 653 | lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
655 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 654 | void *arg, uint32_t evt) |
656 | { | 655 | { |
657 | struct lpfc_iocbq *cmdiocb; | 656 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
658 | |||
659 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
660 | 657 | ||
661 | /* software abort outstanding PLOGI */ | 658 | /* software abort outstanding PLOGI */ |
662 | lpfc_els_abort(phba, ndlp); | 659 | lpfc_els_abort(vport->phba, ndlp); |
663 | 660 | ||
664 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 661 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
665 | return ndlp->nlp_state; | 662 | return ndlp->nlp_state; |
666 | } | 663 | } |
667 | 664 | ||
668 | static uint32_t | 665 | static uint32_t |
669 | lpfc_rcv_els_plogi_issue(struct lpfc_hba * phba, | 666 | lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
670 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 667 | void *arg, uint32_t evt) |
671 | { | 668 | { |
672 | struct lpfc_iocbq *cmdiocb; | 669 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
673 | 670 | struct lpfc_hba *phba = vport->phba; | |
674 | cmdiocb = (struct lpfc_iocbq *) arg; | 671 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
675 | 672 | ||
676 | /* software abort outstanding PLOGI */ | 673 | /* software abort outstanding PLOGI */ |
677 | lpfc_els_abort(phba, ndlp); | 674 | lpfc_els_abort(phba, ndlp); |
678 | 675 | ||
679 | if (evt == NLP_EVT_RCV_LOGO) { | 676 | if (evt == NLP_EVT_RCV_LOGO) { |
680 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 677 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
681 | } else { | 678 | } else { |
682 | lpfc_issue_els_logo(phba, ndlp, 0); | 679 | lpfc_issue_els_logo(vport, ndlp, 0); |
683 | } | 680 | } |
684 | 681 | ||
685 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 682 | /* Put ndlp in npr state set plogi timer for 1 sec */ |
686 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 683 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
687 | spin_lock_irq(phba->host->host_lock); | 684 | spin_lock_irq(shost->host_lock); |
688 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 685 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
689 | spin_unlock_irq(phba->host->host_lock); | 686 | spin_unlock_irq(shost->host_lock); |
690 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 687 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
691 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | 688 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; |
692 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 689 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
693 | 690 | ||
694 | return ndlp->nlp_state; | 691 | return ndlp->nlp_state; |
695 | } | 692 | } |
696 | 693 | ||
697 | static uint32_t | 694 | static uint32_t |
698 | lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | 695 | lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, |
699 | struct lpfc_nodelist * ndlp, void *arg, | 696 | struct lpfc_nodelist *ndlp, |
697 | void *arg, | ||
700 | uint32_t evt) | 698 | uint32_t evt) |
701 | { | 699 | { |
702 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 700 | struct lpfc_hba *phba = vport->phba; |
701 | struct lpfc_iocbq *cmdiocb, *rspiocb; | ||
703 | struct lpfc_dmabuf *pcmd, *prsp, *mp; | 702 | struct lpfc_dmabuf *pcmd, *prsp, *mp; |
704 | uint32_t *lp; | 703 | uint32_t *lp; |
705 | IOCB_t *irsp; | 704 | IOCB_t *irsp; |
@@ -721,13 +720,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
721 | 720 | ||
722 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 721 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
723 | 722 | ||
724 | prsp = list_get_first(&pcmd->list, | 723 | prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list); |
725 | struct lpfc_dmabuf, | ||
726 | list); | ||
727 | lp = (uint32_t *) prsp->virt; | ||
728 | 724 | ||
725 | lp = (uint32_t *) prsp->virt; | ||
729 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); | 726 | sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t)); |
730 | if (!lpfc_check_sparm(phba, ndlp, sp, CLASS3)) | 727 | if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3)) |
731 | goto out; | 728 | goto out; |
732 | 729 | ||
733 | /* PLOGI chkparm OK */ | 730 | /* PLOGI chkparm OK */ |
@@ -740,12 +737,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
740 | ndlp->nlp_DID, ndlp->nlp_state, | 737 | ndlp->nlp_DID, ndlp->nlp_state, |
741 | ndlp->nlp_flag, ndlp->nlp_rpi); | 738 | ndlp->nlp_flag, ndlp->nlp_rpi); |
742 | 739 | ||
743 | if ((phba->cfg_fcp_class == 2) && | 740 | if (phba->cfg_fcp_class == 2 && (sp->cls2.classValid)) |
744 | (sp->cls2.classValid)) { | ||
745 | ndlp->nlp_fcp_info |= CLASS2; | 741 | ndlp->nlp_fcp_info |= CLASS2; |
746 | } else { | 742 | else |
747 | ndlp->nlp_fcp_info |= CLASS3; | 743 | ndlp->nlp_fcp_info |= CLASS3; |
748 | } | 744 | |
749 | ndlp->nlp_class_sup = 0; | 745 | ndlp->nlp_class_sup = 0; |
750 | if (sp->cls1.classValid) | 746 | if (sp->cls1.classValid) |
751 | ndlp->nlp_class_sup |= FC_COS_CLASS1; | 747 | ndlp->nlp_class_sup |= FC_COS_CLASS1; |
@@ -756,14 +752,14 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
756 | if (sp->cls4.classValid) | 752 | if (sp->cls4.classValid) |
757 | ndlp->nlp_class_sup |= FC_COS_CLASS4; | 753 | ndlp->nlp_class_sup |= FC_COS_CLASS4; |
758 | ndlp->nlp_maxframe = | 754 | ndlp->nlp_maxframe = |
759 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | | 755 | ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb; |
760 | sp->cmn.bbRcvSizeLsb; | ||
761 | 756 | ||
762 | if (!(mbox = mempool_alloc(phba->mbox_mem_pool, | 757 | mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
763 | GFP_KERNEL))) | 758 | if (!mbox) |
764 | goto out; | 759 | goto out; |
765 | 760 | ||
766 | lpfc_unreg_rpi(phba, ndlp); | 761 | lpfc_unreg_rpi(vport, ndlp); |
762 | |||
767 | if (lpfc_reg_login(phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp, | 763 | if (lpfc_reg_login(phba, irsp->un.elsreq64.remoteID, (uint8_t *) sp, |
768 | mbox, 0) == 0) { | 764 | mbox, 0) == 0) { |
769 | switch (ndlp->nlp_DID) { | 765 | switch (ndlp->nlp_DID) { |
@@ -777,10 +773,12 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
777 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | 773 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; |
778 | } | 774 | } |
779 | mbox->context2 = lpfc_nlp_get(ndlp); | 775 | mbox->context2 = lpfc_nlp_get(ndlp); |
776 | mbox->vport = vport; | ||
780 | if (lpfc_sli_issue_mbox(phba, mbox, | 777 | if (lpfc_sli_issue_mbox(phba, mbox, |
781 | (MBX_NOWAIT | MBX_STOP_IOCB)) | 778 | (MBX_NOWAIT | MBX_STOP_IOCB)) |
782 | != MBX_NOT_FINISHED) { | 779 | != MBX_NOT_FINISHED) { |
783 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); | 780 | lpfc_nlp_set_state(vport, ndlp, |
781 | NLP_STE_REG_LOGIN_ISSUE); | ||
784 | return ndlp->nlp_state; | 782 | return ndlp->nlp_state; |
785 | } | 783 | } |
786 | lpfc_nlp_put(ndlp); | 784 | lpfc_nlp_put(ndlp); |
@@ -796,49 +794,56 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_hba * phba, | |||
796 | out: | 794 | out: |
797 | /* Free this node since the driver cannot login or has the wrong | 795 | /* Free this node since the driver cannot login or has the wrong |
798 | sparm */ | 796 | sparm */ |
799 | lpfc_drop_node(phba, ndlp); | 797 | lpfc_drop_node(vport, ndlp); |
800 | return NLP_STE_FREED_NODE; | 798 | return NLP_STE_FREED_NODE; |
801 | } | 799 | } |
802 | 800 | ||
803 | static uint32_t | 801 | static uint32_t |
804 | lpfc_device_rm_plogi_issue(struct lpfc_hba * phba, | 802 | lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
805 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 803 | void *arg, uint32_t evt) |
806 | { | 804 | { |
807 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 805 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
806 | |||
807 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
808 | spin_lock_irq(shost->host_lock); | ||
808 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 809 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
810 | spin_unlock_irq(shost->host_lock); | ||
809 | return ndlp->nlp_state; | 811 | return ndlp->nlp_state; |
810 | } | 812 | } else { |
811 | else { | ||
812 | /* software abort outstanding PLOGI */ | 813 | /* software abort outstanding PLOGI */ |
813 | lpfc_els_abort(phba, ndlp); | 814 | lpfc_els_abort(vport->phba, ndlp); |
814 | 815 | ||
815 | lpfc_drop_node(phba, ndlp); | 816 | lpfc_drop_node(vport, ndlp); |
816 | return NLP_STE_FREED_NODE; | 817 | return NLP_STE_FREED_NODE; |
817 | } | 818 | } |
818 | } | 819 | } |
819 | 820 | ||
820 | static uint32_t | 821 | static uint32_t |
821 | lpfc_device_recov_plogi_issue(struct lpfc_hba * phba, | 822 | lpfc_device_recov_plogi_issue(struct lpfc_vport *vport, |
822 | struct lpfc_nodelist * ndlp, void *arg, | 823 | struct lpfc_nodelist *ndlp, |
823 | uint32_t evt) | 824 | void *arg, |
825 | uint32_t evt) | ||
824 | { | 826 | { |
827 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
828 | struct lpfc_hba *phba = vport->phba; | ||
829 | |||
825 | /* software abort outstanding PLOGI */ | 830 | /* software abort outstanding PLOGI */ |
826 | lpfc_els_abort(phba, ndlp); | 831 | lpfc_els_abort(phba, ndlp); |
827 | 832 | ||
828 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; | 833 | ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE; |
829 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 834 | spin_lock_irq(shost->host_lock); |
830 | spin_lock_irq(phba->host->host_lock); | 835 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
831 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 836 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
832 | spin_unlock_irq(phba->host->host_lock); | 837 | spin_unlock_irq(shost->host_lock); |
833 | 838 | ||
834 | return ndlp->nlp_state; | 839 | return ndlp->nlp_state; |
835 | } | 840 | } |
836 | 841 | ||
837 | static uint32_t | 842 | static uint32_t |
838 | lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, | 843 | lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
839 | struct lpfc_nodelist * ndlp, void *arg, | 844 | void *arg, uint32_t evt) |
840 | uint32_t evt) | ||
841 | { | 845 | { |
846 | struct lpfc_hba *phba = vport->phba; | ||
842 | struct lpfc_iocbq *cmdiocb; | 847 | struct lpfc_iocbq *cmdiocb; |
843 | 848 | ||
844 | /* software abort outstanding ADISC */ | 849 | /* software abort outstanding ADISC */ |
@@ -846,34 +851,31 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_hba * phba, | |||
846 | 851 | ||
847 | cmdiocb = (struct lpfc_iocbq *) arg; | 852 | cmdiocb = (struct lpfc_iocbq *) arg; |
848 | 853 | ||
849 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 854 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) |
850 | return ndlp->nlp_state; | 855 | return ndlp->nlp_state; |
851 | } | 856 | |
852 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 857 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
853 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 858 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
854 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 859 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
855 | 860 | ||
856 | return ndlp->nlp_state; | 861 | return ndlp->nlp_state; |
857 | } | 862 | } |
858 | 863 | ||
859 | static uint32_t | 864 | static uint32_t |
860 | lpfc_rcv_prli_adisc_issue(struct lpfc_hba * phba, | 865 | lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
861 | struct lpfc_nodelist * ndlp, void *arg, | 866 | void *arg, uint32_t evt) |
862 | uint32_t evt) | ||
863 | { | 867 | { |
864 | struct lpfc_iocbq *cmdiocb; | 868 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
865 | |||
866 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
867 | 869 | ||
868 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 870 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
869 | return ndlp->nlp_state; | 871 | return ndlp->nlp_state; |
870 | } | 872 | } |
871 | 873 | ||
872 | static uint32_t | 874 | static uint32_t |
873 | lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, | 875 | lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
874 | struct lpfc_nodelist * ndlp, void *arg, | 876 | void *arg, uint32_t evt) |
875 | uint32_t evt) | ||
876 | { | 877 | { |
878 | struct lpfc_hba *phba = vport->phba; | ||
877 | struct lpfc_iocbq *cmdiocb; | 879 | struct lpfc_iocbq *cmdiocb; |
878 | 880 | ||
879 | cmdiocb = (struct lpfc_iocbq *) arg; | 881 | cmdiocb = (struct lpfc_iocbq *) arg; |
@@ -881,42 +883,43 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, | |||
881 | /* software abort outstanding ADISC */ | 883 | /* software abort outstanding ADISC */ |
882 | lpfc_els_abort(phba, ndlp); | 884 | lpfc_els_abort(phba, ndlp); |
883 | 885 | ||
884 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 886 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
885 | return ndlp->nlp_state; | 887 | return ndlp->nlp_state; |
886 | } | 888 | } |
887 | 889 | ||
888 | static uint32_t | 890 | static uint32_t |
889 | lpfc_rcv_padisc_adisc_issue(struct lpfc_hba * phba, | 891 | lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport, |
890 | struct lpfc_nodelist * ndlp, void *arg, | 892 | struct lpfc_nodelist *ndlp, |
891 | uint32_t evt) | 893 | void *arg, uint32_t evt) |
892 | { | 894 | { |
893 | struct lpfc_iocbq *cmdiocb; | 895 | struct lpfc_iocbq *cmdiocb; |
894 | 896 | ||
895 | cmdiocb = (struct lpfc_iocbq *) arg; | 897 | cmdiocb = (struct lpfc_iocbq *) arg; |
896 | 898 | ||
897 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 899 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
898 | return ndlp->nlp_state; | 900 | return ndlp->nlp_state; |
899 | } | 901 | } |
900 | 902 | ||
901 | static uint32_t | 903 | static uint32_t |
902 | lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, | 904 | lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
903 | struct lpfc_nodelist * ndlp, void *arg, | 905 | void *arg, uint32_t evt) |
904 | uint32_t evt) | ||
905 | { | 906 | { |
906 | struct lpfc_iocbq *cmdiocb; | 907 | struct lpfc_iocbq *cmdiocb; |
907 | 908 | ||
908 | cmdiocb = (struct lpfc_iocbq *) arg; | 909 | cmdiocb = (struct lpfc_iocbq *) arg; |
909 | 910 | ||
910 | /* Treat like rcv logo */ | 911 | /* Treat like rcv logo */ |
911 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); | 912 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO); |
912 | return ndlp->nlp_state; | 913 | return ndlp->nlp_state; |
913 | } | 914 | } |
914 | 915 | ||
915 | static uint32_t | 916 | static uint32_t |
916 | lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, | 917 | lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, |
917 | struct lpfc_nodelist * ndlp, void *arg, | 918 | struct lpfc_nodelist *ndlp, |
918 | uint32_t evt) | 919 | void *arg, uint32_t evt) |
919 | { | 920 | { |
921 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
922 | struct lpfc_hba *phba = vport->phba; | ||
920 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 923 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
921 | IOCB_t *irsp; | 924 | IOCB_t *irsp; |
922 | ADISC *ap; | 925 | ADISC *ap; |
@@ -928,101 +931,107 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_hba * phba, | |||
928 | irsp = &rspiocb->iocb; | 931 | irsp = &rspiocb->iocb; |
929 | 932 | ||
930 | if ((irsp->ulpStatus) || | 933 | if ((irsp->ulpStatus) || |
931 | (!lpfc_check_adisc(phba, ndlp, &ap->nodeName, &ap->portName))) { | 934 | (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) { |
932 | /* 1 sec timeout */ | 935 | /* 1 sec timeout */ |
933 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); | 936 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); |
934 | spin_lock_irq(phba->host->host_lock); | 937 | spin_lock_irq(shost->host_lock); |
935 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 938 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
936 | spin_unlock_irq(phba->host->host_lock); | 939 | spin_unlock_irq(shost->host_lock); |
937 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 940 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
938 | 941 | ||
939 | memset(&ndlp->nlp_nodename, 0, sizeof (struct lpfc_name)); | 942 | memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name)); |
940 | memset(&ndlp->nlp_portname, 0, sizeof (struct lpfc_name)); | 943 | memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name)); |
941 | 944 | ||
942 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 945 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
943 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 946 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
944 | lpfc_unreg_rpi(phba, ndlp); | 947 | lpfc_unreg_rpi(vport, ndlp); |
945 | return ndlp->nlp_state; | 948 | return ndlp->nlp_state; |
946 | } | 949 | } |
947 | 950 | ||
948 | if (ndlp->nlp_type & NLP_FCP_TARGET) { | 951 | if (ndlp->nlp_type & NLP_FCP_TARGET) { |
949 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 952 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
950 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE); | 953 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); |
951 | } else { | 954 | } else { |
952 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 955 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
953 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 956 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
954 | } | 957 | } |
955 | return ndlp->nlp_state; | 958 | return ndlp->nlp_state; |
956 | } | 959 | } |
957 | 960 | ||
958 | static uint32_t | 961 | static uint32_t |
959 | lpfc_device_rm_adisc_issue(struct lpfc_hba * phba, | 962 | lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
960 | struct lpfc_nodelist * ndlp, void *arg, | 963 | void *arg, uint32_t evt) |
961 | uint32_t evt) | ||
962 | { | 964 | { |
963 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 965 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
966 | |||
967 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
968 | spin_lock_irq(shost->host_lock); | ||
964 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 969 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
970 | spin_unlock_irq(shost->host_lock); | ||
965 | return ndlp->nlp_state; | 971 | return ndlp->nlp_state; |
966 | } | 972 | } else { |
967 | else { | ||
968 | /* software abort outstanding ADISC */ | 973 | /* software abort outstanding ADISC */ |
969 | lpfc_els_abort(phba, ndlp); | 974 | lpfc_els_abort(vport->phba, ndlp); |
970 | 975 | ||
971 | lpfc_drop_node(phba, ndlp); | 976 | lpfc_drop_node(vport, ndlp); |
972 | return NLP_STE_FREED_NODE; | 977 | return NLP_STE_FREED_NODE; |
973 | } | 978 | } |
974 | } | 979 | } |
975 | 980 | ||
976 | static uint32_t | 981 | static uint32_t |
977 | lpfc_device_recov_adisc_issue(struct lpfc_hba * phba, | 982 | lpfc_device_recov_adisc_issue(struct lpfc_vport *vport, |
978 | struct lpfc_nodelist * ndlp, void *arg, | 983 | struct lpfc_nodelist *ndlp, |
979 | uint32_t evt) | 984 | void *arg, |
985 | uint32_t evt) | ||
980 | { | 986 | { |
987 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
988 | struct lpfc_hba *phba = vport->phba; | ||
989 | |||
981 | /* software abort outstanding ADISC */ | 990 | /* software abort outstanding ADISC */ |
982 | lpfc_els_abort(phba, ndlp); | 991 | lpfc_els_abort(phba, ndlp); |
983 | 992 | ||
984 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; | 993 | ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE; |
985 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 994 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
986 | spin_lock_irq(phba->host->host_lock); | 995 | spin_lock_irq(shost->host_lock); |
987 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 996 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
988 | ndlp->nlp_flag |= NLP_NPR_ADISC; | 997 | ndlp->nlp_flag |= NLP_NPR_ADISC; |
989 | spin_unlock_irq(phba->host->host_lock); | 998 | spin_unlock_irq(shost->host_lock); |
990 | 999 | ||
991 | return ndlp->nlp_state; | 1000 | return ndlp->nlp_state; |
992 | } | 1001 | } |
993 | 1002 | ||
994 | static uint32_t | 1003 | static uint32_t |
995 | lpfc_rcv_plogi_reglogin_issue(struct lpfc_hba * phba, | 1004 | lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport, |
996 | struct lpfc_nodelist * ndlp, void *arg, | 1005 | struct lpfc_nodelist *ndlp, |
1006 | void *arg, | ||
997 | uint32_t evt) | 1007 | uint32_t evt) |
998 | { | 1008 | { |
999 | struct lpfc_iocbq *cmdiocb; | 1009 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1000 | |||
1001 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1002 | 1010 | ||
1003 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1011 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1004 | return ndlp->nlp_state; | 1012 | return ndlp->nlp_state; |
1005 | } | 1013 | } |
1006 | 1014 | ||
1007 | static uint32_t | 1015 | static uint32_t |
1008 | lpfc_rcv_prli_reglogin_issue(struct lpfc_hba * phba, | 1016 | lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport, |
1009 | struct lpfc_nodelist * ndlp, void *arg, | 1017 | struct lpfc_nodelist *ndlp, |
1018 | void *arg, | ||
1010 | uint32_t evt) | 1019 | uint32_t evt) |
1011 | { | 1020 | { |
1012 | struct lpfc_iocbq *cmdiocb; | 1021 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1013 | |||
1014 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1015 | 1022 | ||
1016 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1023 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
1017 | return ndlp->nlp_state; | 1024 | return ndlp->nlp_state; |
1018 | } | 1025 | } |
1019 | 1026 | ||
1020 | static uint32_t | 1027 | static uint32_t |
1021 | lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | 1028 | lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport, |
1022 | struct lpfc_nodelist * ndlp, void *arg, | 1029 | struct lpfc_nodelist *ndlp, |
1030 | void *arg, | ||
1023 | uint32_t evt) | 1031 | uint32_t evt) |
1024 | { | 1032 | { |
1025 | struct lpfc_iocbq *cmdiocb; | 1033 | struct lpfc_hba *phba = vport->phba; |
1034 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | ||
1026 | LPFC_MBOXQ_t *mb; | 1035 | LPFC_MBOXQ_t *mb; |
1027 | LPFC_MBOXQ_t *nextmb; | 1036 | LPFC_MBOXQ_t *nextmb; |
1028 | struct lpfc_dmabuf *mp; | 1037 | struct lpfc_dmabuf *mp; |
@@ -1038,7 +1047,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | |||
1038 | } | 1047 | } |
1039 | } | 1048 | } |
1040 | 1049 | ||
1041 | spin_lock_irq(phba->host->host_lock); | 1050 | spin_lock_irq(&phba->hbalock); |
1042 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 1051 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
1043 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && | 1052 | if ((mb->mb.mbxCommand == MBX_REG_LOGIN64) && |
1044 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 1053 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
@@ -1051,49 +1060,49 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, | |||
1051 | mempool_free(mb, phba->mbox_mem_pool); | 1060 | mempool_free(mb, phba->mbox_mem_pool); |
1052 | } | 1061 | } |
1053 | } | 1062 | } |
1054 | spin_unlock_irq(phba->host->host_lock); | 1063 | spin_unlock_irq(&phba->hbalock); |
1055 | 1064 | ||
1056 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1065 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1057 | return ndlp->nlp_state; | 1066 | return ndlp->nlp_state; |
1058 | } | 1067 | } |
1059 | 1068 | ||
1060 | static uint32_t | 1069 | static uint32_t |
1061 | lpfc_rcv_padisc_reglogin_issue(struct lpfc_hba * phba, | 1070 | lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport, |
1062 | struct lpfc_nodelist * ndlp, void *arg, | 1071 | struct lpfc_nodelist *ndlp, |
1072 | void *arg, | ||
1063 | uint32_t evt) | 1073 | uint32_t evt) |
1064 | { | 1074 | { |
1065 | struct lpfc_iocbq *cmdiocb; | 1075 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1066 | 1076 | ||
1067 | cmdiocb = (struct lpfc_iocbq *) arg; | 1077 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1068 | |||
1069 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | ||
1070 | return ndlp->nlp_state; | 1078 | return ndlp->nlp_state; |
1071 | } | 1079 | } |
1072 | 1080 | ||
1073 | static uint32_t | 1081 | static uint32_t |
1074 | lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, | 1082 | lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport, |
1075 | struct lpfc_nodelist * ndlp, void *arg, | 1083 | struct lpfc_nodelist *ndlp, |
1084 | void *arg, | ||
1076 | uint32_t evt) | 1085 | uint32_t evt) |
1077 | { | 1086 | { |
1078 | struct lpfc_iocbq *cmdiocb; | 1087 | struct lpfc_iocbq *cmdiocb; |
1079 | 1088 | ||
1080 | cmdiocb = (struct lpfc_iocbq *) arg; | 1089 | cmdiocb = (struct lpfc_iocbq *) arg; |
1081 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | 1090 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1082 | return ndlp->nlp_state; | 1091 | return ndlp->nlp_state; |
1083 | } | 1092 | } |
1084 | 1093 | ||
1085 | static uint32_t | 1094 | static uint32_t |
1086 | lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | 1095 | lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport, |
1087 | struct lpfc_nodelist * ndlp, | 1096 | struct lpfc_nodelist *ndlp, |
1088 | void *arg, uint32_t evt) | 1097 | void *arg, |
1098 | uint32_t evt) | ||
1089 | { | 1099 | { |
1090 | LPFC_MBOXQ_t *pmb; | 1100 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1091 | MAILBOX_t *mb; | 1101 | struct lpfc_hba *phba = vport->phba; |
1092 | uint32_t did; | 1102 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
1103 | MAILBOX_t *mb = &pmb->mb; | ||
1104 | uint32_t did = mb->un.varWords[1]; | ||
1093 | 1105 | ||
1094 | pmb = (LPFC_MBOXQ_t *) arg; | ||
1095 | mb = &pmb->mb; | ||
1096 | did = mb->un.varWords[1]; | ||
1097 | if (mb->mbxStatus) { | 1106 | if (mb->mbxStatus) { |
1098 | /* RegLogin failed */ | 1107 | /* RegLogin failed */ |
1099 | lpfc_printf_log(phba, | 1108 | lpfc_printf_log(phba, |
@@ -1101,7 +1110,7 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1101 | LOG_DISCOVERY, | 1110 | LOG_DISCOVERY, |
1102 | "%d:0246 RegLogin failed Data: x%x x%x x%x\n", | 1111 | "%d:0246 RegLogin failed Data: x%x x%x x%x\n", |
1103 | phba->brd_no, | 1112 | phba->brd_no, |
1104 | did, mb->mbxStatus, phba->hba_state); | 1113 | did, mb->mbxStatus, vport->port_state); |
1105 | 1114 | ||
1106 | /* | 1115 | /* |
1107 | * If RegLogin failed due to lack of HBA resources do not | 1116 | * If RegLogin failed due to lack of HBA resources do not |
@@ -1109,20 +1118,20 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1109 | */ | 1118 | */ |
1110 | if (mb->mbxStatus == MBXERR_RPI_FULL) { | 1119 | if (mb->mbxStatus == MBXERR_RPI_FULL) { |
1111 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; | 1120 | ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE; |
1112 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNUSED_NODE); | 1121 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); |
1113 | return ndlp->nlp_state; | 1122 | return ndlp->nlp_state; |
1114 | } | 1123 | } |
1115 | 1124 | ||
1116 | /* Put ndlp in npr list set plogi timer for 1 sec */ | 1125 | /* Put ndlp in npr state set plogi timer for 1 sec */ |
1117 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1126 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1118 | spin_lock_irq(phba->host->host_lock); | 1127 | spin_lock_irq(shost->host_lock); |
1119 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1128 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1120 | spin_unlock_irq(phba->host->host_lock); | 1129 | spin_unlock_irq(shost->host_lock); |
1121 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 1130 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
1122 | 1131 | ||
1123 | lpfc_issue_els_logo(phba, ndlp, 0); | 1132 | lpfc_issue_els_logo(vport, ndlp, 0); |
1124 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1133 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1125 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1134 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1126 | return ndlp->nlp_state; | 1135 | return ndlp->nlp_state; |
1127 | } | 1136 | } |
1128 | 1137 | ||
@@ -1131,91 +1140,92 @@ lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_hba * phba, | |||
1131 | /* Only if we are not a fabric nport do we issue PRLI */ | 1140 | /* Only if we are not a fabric nport do we issue PRLI */ |
1132 | if (!(ndlp->nlp_type & NLP_FABRIC)) { | 1141 | if (!(ndlp->nlp_type & NLP_FABRIC)) { |
1133 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1142 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1134 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PRLI_ISSUE); | 1143 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE); |
1135 | lpfc_issue_els_prli(phba, ndlp, 0); | 1144 | lpfc_issue_els_prli(vport, ndlp, 0); |
1136 | } else { | 1145 | } else { |
1137 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1146 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1138 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1147 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1139 | } | 1148 | } |
1140 | return ndlp->nlp_state; | 1149 | return ndlp->nlp_state; |
1141 | } | 1150 | } |
1142 | 1151 | ||
1143 | static uint32_t | 1152 | static uint32_t |
1144 | lpfc_device_rm_reglogin_issue(struct lpfc_hba * phba, | 1153 | lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport, |
1145 | struct lpfc_nodelist * ndlp, void *arg, | 1154 | struct lpfc_nodelist *ndlp, |
1155 | void *arg, | ||
1146 | uint32_t evt) | 1156 | uint32_t evt) |
1147 | { | 1157 | { |
1148 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 1158 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1159 | |||
1160 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
1161 | spin_lock_irq(shost->host_lock); | ||
1149 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 1162 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1163 | spin_unlock_irq(shost->host_lock); | ||
1150 | return ndlp->nlp_state; | 1164 | return ndlp->nlp_state; |
1151 | } | 1165 | } else { |
1152 | else { | 1166 | lpfc_drop_node(vport, ndlp); |
1153 | lpfc_drop_node(phba, ndlp); | ||
1154 | return NLP_STE_FREED_NODE; | 1167 | return NLP_STE_FREED_NODE; |
1155 | } | 1168 | } |
1156 | } | 1169 | } |
1157 | 1170 | ||
1158 | static uint32_t | 1171 | static uint32_t |
1159 | lpfc_device_recov_reglogin_issue(struct lpfc_hba * phba, | 1172 | lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport, |
1160 | struct lpfc_nodelist * ndlp, void *arg, | 1173 | struct lpfc_nodelist *ndlp, |
1161 | uint32_t evt) | 1174 | void *arg, |
1175 | uint32_t evt) | ||
1162 | { | 1176 | { |
1177 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1178 | |||
1163 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; | 1179 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
1164 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1180 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1165 | spin_lock_irq(phba->host->host_lock); | 1181 | spin_lock_irq(shost->host_lock); |
1166 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1182 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1167 | spin_unlock_irq(phba->host->host_lock); | 1183 | spin_unlock_irq(shost->host_lock); |
1168 | return ndlp->nlp_state; | 1184 | return ndlp->nlp_state; |
1169 | } | 1185 | } |
1170 | 1186 | ||
1171 | static uint32_t | 1187 | static uint32_t |
1172 | lpfc_rcv_plogi_prli_issue(struct lpfc_hba * phba, | 1188 | lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1173 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1189 | void *arg, uint32_t evt) |
1174 | { | 1190 | { |
1175 | struct lpfc_iocbq *cmdiocb; | 1191 | struct lpfc_iocbq *cmdiocb; |
1176 | 1192 | ||
1177 | cmdiocb = (struct lpfc_iocbq *) arg; | 1193 | cmdiocb = (struct lpfc_iocbq *) arg; |
1178 | 1194 | ||
1179 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | 1195 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1180 | return ndlp->nlp_state; | 1196 | return ndlp->nlp_state; |
1181 | } | 1197 | } |
1182 | 1198 | ||
1183 | static uint32_t | 1199 | static uint32_t |
1184 | lpfc_rcv_prli_prli_issue(struct lpfc_hba * phba, | 1200 | lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1185 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1201 | void *arg, uint32_t evt) |
1186 | { | 1202 | { |
1187 | struct lpfc_iocbq *cmdiocb; | 1203 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1188 | |||
1189 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1190 | 1204 | ||
1191 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | 1205 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
1192 | return ndlp->nlp_state; | 1206 | return ndlp->nlp_state; |
1193 | } | 1207 | } |
1194 | 1208 | ||
1195 | static uint32_t | 1209 | static uint32_t |
1196 | lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, | 1210 | lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1197 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1211 | void *arg, uint32_t evt) |
1198 | { | 1212 | { |
1199 | struct lpfc_iocbq *cmdiocb; | 1213 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1200 | |||
1201 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1202 | 1214 | ||
1203 | /* Software abort outstanding PRLI before sending acc */ | 1215 | /* Software abort outstanding PRLI before sending acc */ |
1204 | lpfc_els_abort(phba, ndlp); | 1216 | lpfc_els_abort(vport->phba, ndlp); |
1205 | 1217 | ||
1206 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1218 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1207 | return ndlp->nlp_state; | 1219 | return ndlp->nlp_state; |
1208 | } | 1220 | } |
1209 | 1221 | ||
1210 | static uint32_t | 1222 | static uint32_t |
1211 | lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, | 1223 | lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1212 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1224 | void *arg, uint32_t evt) |
1213 | { | 1225 | { |
1214 | struct lpfc_iocbq *cmdiocb; | 1226 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1215 | |||
1216 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1217 | 1227 | ||
1218 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1228 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1219 | return ndlp->nlp_state; | 1229 | return ndlp->nlp_state; |
1220 | } | 1230 | } |
1221 | 1231 | ||
@@ -1225,21 +1235,21 @@ lpfc_rcv_padisc_prli_issue(struct lpfc_hba * phba, | |||
1225 | * NEXT STATE = PRLI_ISSUE | 1235 | * NEXT STATE = PRLI_ISSUE |
1226 | */ | 1236 | */ |
1227 | static uint32_t | 1237 | static uint32_t |
1228 | lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, | 1238 | lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1229 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1239 | void *arg, uint32_t evt) |
1230 | { | 1240 | { |
1231 | struct lpfc_iocbq *cmdiocb; | 1241 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1232 | 1242 | ||
1233 | cmdiocb = (struct lpfc_iocbq *) arg; | 1243 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1234 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | ||
1235 | return ndlp->nlp_state; | 1244 | return ndlp->nlp_state; |
1236 | } | 1245 | } |
1237 | 1246 | ||
1238 | static uint32_t | 1247 | static uint32_t |
1239 | lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | 1248 | lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1240 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1249 | void *arg, uint32_t evt) |
1241 | { | 1250 | { |
1242 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1251 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1252 | struct lpfc_hba *phba = vport->phba; | ||
1243 | IOCB_t *irsp; | 1253 | IOCB_t *irsp; |
1244 | PRLI *npr; | 1254 | PRLI *npr; |
1245 | 1255 | ||
@@ -1250,7 +1260,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1250 | irsp = &rspiocb->iocb; | 1260 | irsp = &rspiocb->iocb; |
1251 | if (irsp->ulpStatus) { | 1261 | if (irsp->ulpStatus) { |
1252 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | 1262 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; |
1253 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); | 1263 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); |
1254 | return ndlp->nlp_state; | 1264 | return ndlp->nlp_state; |
1255 | } | 1265 | } |
1256 | 1266 | ||
@@ -1268,7 +1278,7 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1268 | } | 1278 | } |
1269 | 1279 | ||
1270 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | 1280 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; |
1271 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_MAPPED_NODE); | 1281 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE); |
1272 | return ndlp->nlp_state; | 1282 | return ndlp->nlp_state; |
1273 | } | 1283 | } |
1274 | 1284 | ||
@@ -1286,22 +1296,25 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_hba * phba, | |||
1286 | * This routine is envoked when we a request to remove a nport we are in the | 1296 | * This routine is envoked when we a request to remove a nport we are in the |
1287 | * process of PRLIing. We should software abort outstanding prli, unreg | 1297 | * process of PRLIing. We should software abort outstanding prli, unreg |
1288 | * login, send a logout. We will change node state to UNUSED_NODE, put it | 1298 | * login, send a logout. We will change node state to UNUSED_NODE, put it |
1289 | * on plogi list so it can be freed when LOGO completes. | 1299 | * in plogi state so it can be freed when LOGO completes. |
1290 | * | 1300 | * |
1291 | */ | 1301 | */ |
1292 | static uint32_t | 1302 | static uint32_t |
1293 | lpfc_device_rm_prli_issue(struct lpfc_hba * phba, | 1303 | lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1294 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1304 | void *arg, uint32_t evt) |
1295 | { | 1305 | { |
1296 | if(ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 1306 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1307 | |||
1308 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | ||
1309 | spin_lock_irq(shost->host_lock); | ||
1297 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 1310 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1311 | spin_unlock_irq(shost->host_lock); | ||
1298 | return ndlp->nlp_state; | 1312 | return ndlp->nlp_state; |
1299 | } | 1313 | } else { |
1300 | else { | ||
1301 | /* software abort outstanding PLOGI */ | 1314 | /* software abort outstanding PLOGI */ |
1302 | lpfc_els_abort(phba, ndlp); | 1315 | lpfc_els_abort(vport->phba, ndlp); |
1303 | 1316 | ||
1304 | lpfc_drop_node(phba, ndlp); | 1317 | lpfc_drop_node(vport, ndlp); |
1305 | return NLP_STE_FREED_NODE; | 1318 | return NLP_STE_FREED_NODE; |
1306 | } | 1319 | } |
1307 | } | 1320 | } |
@@ -1324,261 +1337,247 @@ lpfc_device_rm_prli_issue(struct lpfc_hba * phba, | |||
1324 | * outstanding PRLI command, then free the node entry. | 1337 | * outstanding PRLI command, then free the node entry. |
1325 | */ | 1338 | */ |
1326 | static uint32_t | 1339 | static uint32_t |
1327 | lpfc_device_recov_prli_issue(struct lpfc_hba * phba, | 1340 | lpfc_device_recov_prli_issue(struct lpfc_vport *vport, |
1328 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1341 | struct lpfc_nodelist *ndlp, |
1342 | void *arg, | ||
1343 | uint32_t evt) | ||
1329 | { | 1344 | { |
1345 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1346 | struct lpfc_hba *phba = vport->phba; | ||
1347 | |||
1330 | /* software abort outstanding PRLI */ | 1348 | /* software abort outstanding PRLI */ |
1331 | lpfc_els_abort(phba, ndlp); | 1349 | lpfc_els_abort(phba, ndlp); |
1332 | 1350 | ||
1333 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; | 1351 | ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE; |
1334 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1352 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1335 | spin_lock_irq(phba->host->host_lock); | 1353 | spin_lock_irq(shost->host_lock); |
1336 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1354 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1337 | spin_unlock_irq(phba->host->host_lock); | 1355 | spin_unlock_irq(shost->host_lock); |
1338 | return ndlp->nlp_state; | 1356 | return ndlp->nlp_state; |
1339 | } | 1357 | } |
1340 | 1358 | ||
1341 | static uint32_t | 1359 | static uint32_t |
1342 | lpfc_rcv_plogi_unmap_node(struct lpfc_hba * phba, | 1360 | lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1343 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1361 | void *arg, uint32_t evt) |
1344 | { | 1362 | { |
1345 | struct lpfc_iocbq *cmdiocb; | 1363 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1346 | 1364 | ||
1347 | cmdiocb = (struct lpfc_iocbq *) arg; | 1365 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1348 | |||
1349 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | ||
1350 | return ndlp->nlp_state; | 1366 | return ndlp->nlp_state; |
1351 | } | 1367 | } |
1352 | 1368 | ||
1353 | static uint32_t | 1369 | static uint32_t |
1354 | lpfc_rcv_prli_unmap_node(struct lpfc_hba * phba, | 1370 | lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1355 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1371 | void *arg, uint32_t evt) |
1356 | { | 1372 | { |
1357 | struct lpfc_iocbq *cmdiocb; | 1373 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1358 | 1374 | ||
1359 | cmdiocb = (struct lpfc_iocbq *) arg; | 1375 | lpfc_rcv_prli(vport, ndlp, cmdiocb); |
1360 | 1376 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); | |
1361 | lpfc_rcv_prli(phba, ndlp, cmdiocb); | ||
1362 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | ||
1363 | return ndlp->nlp_state; | 1377 | return ndlp->nlp_state; |
1364 | } | 1378 | } |
1365 | 1379 | ||
1366 | static uint32_t | 1380 | static uint32_t |
1367 | lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, | 1381 | lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1368 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1382 | void *arg, uint32_t evt) |
1369 | { | 1383 | { |
1370 | struct lpfc_iocbq *cmdiocb; | 1384 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1371 | |||
1372 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1373 | 1385 | ||
1374 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1386 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1375 | return ndlp->nlp_state; | 1387 | return ndlp->nlp_state; |
1376 | } | 1388 | } |
1377 | 1389 | ||
1378 | static uint32_t | 1390 | static uint32_t |
1379 | lpfc_rcv_padisc_unmap_node(struct lpfc_hba * phba, | 1391 | lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1380 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1392 | void *arg, uint32_t evt) |
1381 | { | 1393 | { |
1382 | struct lpfc_iocbq *cmdiocb; | 1394 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1383 | |||
1384 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1385 | 1395 | ||
1386 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1396 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1387 | return ndlp->nlp_state; | 1397 | return ndlp->nlp_state; |
1388 | } | 1398 | } |
1389 | 1399 | ||
1390 | static uint32_t | 1400 | static uint32_t |
1391 | lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, | 1401 | lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1392 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1402 | void *arg, uint32_t evt) |
1393 | { | 1403 | { |
1394 | struct lpfc_iocbq *cmdiocb; | 1404 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1395 | 1405 | ||
1396 | cmdiocb = (struct lpfc_iocbq *) arg; | 1406 | lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); |
1397 | |||
1398 | lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0); | ||
1399 | return ndlp->nlp_state; | 1407 | return ndlp->nlp_state; |
1400 | } | 1408 | } |
1401 | 1409 | ||
1402 | static uint32_t | 1410 | static uint32_t |
1403 | lpfc_device_recov_unmap_node(struct lpfc_hba * phba, | 1411 | lpfc_device_recov_unmap_node(struct lpfc_vport *vport, |
1404 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1412 | struct lpfc_nodelist *ndlp, |
1413 | void *arg, | ||
1414 | uint32_t evt) | ||
1405 | { | 1415 | { |
1416 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1417 | |||
1406 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; | 1418 | ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE; |
1407 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1419 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1420 | spin_lock_irq(shost->host_lock); | ||
1408 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1421 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1409 | lpfc_disc_set_adisc(phba, ndlp); | 1422 | spin_unlock_irq(shost->host_lock); |
1423 | lpfc_disc_set_adisc(vport, ndlp); | ||
1410 | 1424 | ||
1411 | return ndlp->nlp_state; | 1425 | return ndlp->nlp_state; |
1412 | } | 1426 | } |
1413 | 1427 | ||
1414 | static uint32_t | 1428 | static uint32_t |
1415 | lpfc_rcv_plogi_mapped_node(struct lpfc_hba * phba, | 1429 | lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1416 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1430 | void *arg, uint32_t evt) |
1417 | { | 1431 | { |
1418 | struct lpfc_iocbq *cmdiocb; | 1432 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1419 | 1433 | ||
1420 | cmdiocb = (struct lpfc_iocbq *) arg; | 1434 | lpfc_rcv_plogi(vport, ndlp, cmdiocb); |
1421 | |||
1422 | lpfc_rcv_plogi(phba, ndlp, cmdiocb); | ||
1423 | return ndlp->nlp_state; | 1435 | return ndlp->nlp_state; |
1424 | } | 1436 | } |
1425 | 1437 | ||
1426 | static uint32_t | 1438 | static uint32_t |
1427 | lpfc_rcv_prli_mapped_node(struct lpfc_hba * phba, | 1439 | lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1428 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1440 | void *arg, uint32_t evt) |
1429 | { | 1441 | { |
1430 | struct lpfc_iocbq *cmdiocb; | 1442 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1431 | 1443 | ||
1432 | cmdiocb = (struct lpfc_iocbq *) arg; | 1444 | lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); |
1433 | |||
1434 | lpfc_els_rsp_prli_acc(phba, cmdiocb, ndlp); | ||
1435 | return ndlp->nlp_state; | 1445 | return ndlp->nlp_state; |
1436 | } | 1446 | } |
1437 | 1447 | ||
1438 | static uint32_t | 1448 | static uint32_t |
1439 | lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, | 1449 | lpfc_rcv_logo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1440 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1450 | void *arg, uint32_t evt) |
1441 | { | 1451 | { |
1442 | struct lpfc_iocbq *cmdiocb; | 1452 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1443 | 1453 | ||
1444 | cmdiocb = (struct lpfc_iocbq *) arg; | 1454 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1445 | |||
1446 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | ||
1447 | return ndlp->nlp_state; | 1455 | return ndlp->nlp_state; |
1448 | } | 1456 | } |
1449 | 1457 | ||
1450 | static uint32_t | 1458 | static uint32_t |
1451 | lpfc_rcv_padisc_mapped_node(struct lpfc_hba * phba, | 1459 | lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport, |
1452 | struct lpfc_nodelist * ndlp, void *arg, | 1460 | struct lpfc_nodelist *ndlp, |
1453 | uint32_t evt) | 1461 | void *arg, uint32_t evt) |
1454 | { | 1462 | { |
1455 | struct lpfc_iocbq *cmdiocb; | 1463 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1456 | |||
1457 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1458 | 1464 | ||
1459 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1465 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1460 | return ndlp->nlp_state; | 1466 | return ndlp->nlp_state; |
1461 | } | 1467 | } |
1462 | 1468 | ||
1463 | static uint32_t | 1469 | static uint32_t |
1464 | lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, | 1470 | lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1465 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1471 | void *arg, uint32_t evt) |
1466 | { | 1472 | { |
1467 | struct lpfc_iocbq *cmdiocb; | 1473 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1468 | 1474 | struct lpfc_hba *phba = vport->phba; | |
1469 | cmdiocb = (struct lpfc_iocbq *) arg; | 1475 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1470 | 1476 | ||
1471 | /* flush the target */ | 1477 | /* flush the target */ |
1472 | spin_lock_irq(phba->host->host_lock); | 1478 | spin_lock_irq(shost->host_lock); |
1473 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], | 1479 | lpfc_sli_abort_iocb(phba, &phba->sli.ring[phba->sli.fcp_ring], |
1474 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); | 1480 | ndlp->nlp_sid, 0, 0, LPFC_CTX_TGT); |
1475 | spin_unlock_irq(phba->host->host_lock); | 1481 | spin_unlock_irq(shost->host_lock); |
1476 | 1482 | ||
1477 | /* Treat like rcv logo */ | 1483 | /* Treat like rcv logo */ |
1478 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO); | 1484 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO); |
1479 | return ndlp->nlp_state; | 1485 | return ndlp->nlp_state; |
1480 | } | 1486 | } |
1481 | 1487 | ||
1482 | static uint32_t | 1488 | static uint32_t |
1483 | lpfc_device_recov_mapped_node(struct lpfc_hba * phba, | 1489 | lpfc_device_recov_mapped_node(struct lpfc_vport *vport, |
1484 | struct lpfc_nodelist * ndlp, void *arg, | 1490 | struct lpfc_nodelist *ndlp, |
1485 | uint32_t evt) | 1491 | void *arg, |
1492 | uint32_t evt) | ||
1486 | { | 1493 | { |
1494 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1495 | |||
1487 | ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; | 1496 | ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE; |
1488 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_NPR_NODE); | 1497 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); |
1489 | spin_lock_irq(phba->host->host_lock); | 1498 | spin_lock_irq(shost->host_lock); |
1490 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1499 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1491 | spin_unlock_irq(phba->host->host_lock); | 1500 | spin_unlock_irq(shost->host_lock); |
1492 | lpfc_disc_set_adisc(phba, ndlp); | 1501 | lpfc_disc_set_adisc(vport, ndlp); |
1493 | return ndlp->nlp_state; | 1502 | return ndlp->nlp_state; |
1494 | } | 1503 | } |
1495 | 1504 | ||
1496 | static uint32_t | 1505 | static uint32_t |
1497 | lpfc_rcv_plogi_npr_node(struct lpfc_hba * phba, | 1506 | lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1498 | struct lpfc_nodelist * ndlp, void *arg, | 1507 | void *arg, uint32_t evt) |
1499 | uint32_t evt) | ||
1500 | { | 1508 | { |
1501 | struct lpfc_iocbq *cmdiocb; | 1509 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1502 | 1510 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | |
1503 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1504 | 1511 | ||
1505 | /* Ignore PLOGI if we have an outstanding LOGO */ | 1512 | /* Ignore PLOGI if we have an outstanding LOGO */ |
1506 | if (ndlp->nlp_flag & NLP_LOGO_SND) { | 1513 | if (ndlp->nlp_flag & NLP_LOGO_SND) { |
1507 | return ndlp->nlp_state; | 1514 | return ndlp->nlp_state; |
1508 | } | 1515 | } |
1509 | 1516 | ||
1510 | if (lpfc_rcv_plogi(phba, ndlp, cmdiocb)) { | 1517 | if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) { |
1511 | spin_lock_irq(phba->host->host_lock); | 1518 | spin_lock_irq(shost->host_lock); |
1512 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1519 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1513 | spin_unlock_irq(phba->host->host_lock); | 1520 | spin_unlock_irq(shost->host_lock); |
1514 | return ndlp->nlp_state; | 1521 | return ndlp->nlp_state; |
1515 | } | 1522 | } |
1516 | 1523 | ||
1517 | /* send PLOGI immediately, move to PLOGI issue state */ | 1524 | /* send PLOGI immediately, move to PLOGI issue state */ |
1518 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1525 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1519 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1526 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1520 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1527 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1521 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 1528 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
1522 | } | 1529 | } |
1523 | 1530 | ||
1524 | return ndlp->nlp_state; | 1531 | return ndlp->nlp_state; |
1525 | } | 1532 | } |
1526 | 1533 | ||
1527 | static uint32_t | 1534 | static uint32_t |
1528 | lpfc_rcv_prli_npr_node(struct lpfc_hba * phba, | 1535 | lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1529 | struct lpfc_nodelist * ndlp, void *arg, | 1536 | void *arg, uint32_t evt) |
1530 | uint32_t evt) | ||
1531 | { | 1537 | { |
1532 | struct lpfc_iocbq *cmdiocb; | 1538 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1533 | struct ls_rjt stat; | 1539 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1534 | 1540 | struct ls_rjt stat; | |
1535 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1536 | 1541 | ||
1537 | memset(&stat, 0, sizeof (struct ls_rjt)); | 1542 | memset(&stat, 0, sizeof (struct ls_rjt)); |
1538 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 1543 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
1539 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 1544 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
1540 | lpfc_els_rsp_reject(phba, stat.un.lsRjtError, cmdiocb, ndlp); | 1545 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); |
1541 | 1546 | ||
1542 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1547 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { |
1543 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1548 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1544 | spin_lock_irq(phba->host->host_lock); | 1549 | spin_lock_irq(shost->host_lock); |
1545 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1550 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1546 | spin_unlock_irq(phba->host->host_lock); | ||
1547 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1551 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1548 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); | 1552 | spin_unlock_irq(shost->host_lock); |
1549 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1553 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); |
1554 | lpfc_issue_els_adisc(vport, ndlp, 0); | ||
1550 | } else { | 1555 | } else { |
1551 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1556 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1552 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1557 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1553 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 1558 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
1554 | } | 1559 | } |
1555 | } | 1560 | } |
1556 | return ndlp->nlp_state; | 1561 | return ndlp->nlp_state; |
1557 | } | 1562 | } |
1558 | 1563 | ||
1559 | static uint32_t | 1564 | static uint32_t |
1560 | lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, | 1565 | lpfc_rcv_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1561 | struct lpfc_nodelist * ndlp, void *arg, | 1566 | void *arg, uint32_t evt) |
1562 | uint32_t evt) | ||
1563 | { | 1567 | { |
1564 | struct lpfc_iocbq *cmdiocb; | 1568 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1565 | |||
1566 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1567 | 1569 | ||
1568 | lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO); | 1570 | lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO); |
1569 | return ndlp->nlp_state; | 1571 | return ndlp->nlp_state; |
1570 | } | 1572 | } |
1571 | 1573 | ||
1572 | static uint32_t | 1574 | static uint32_t |
1573 | lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | 1575 | lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1574 | struct lpfc_nodelist * ndlp, void *arg, | 1576 | void *arg, uint32_t evt) |
1575 | uint32_t evt) | ||
1576 | { | 1577 | { |
1577 | struct lpfc_iocbq *cmdiocb; | 1578 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; |
1578 | |||
1579 | cmdiocb = (struct lpfc_iocbq *) arg; | ||
1580 | 1579 | ||
1581 | lpfc_rcv_padisc(phba, ndlp, cmdiocb); | 1580 | lpfc_rcv_padisc(vport, ndlp, cmdiocb); |
1582 | 1581 | ||
1583 | /* | 1582 | /* |
1584 | * Do not start discovery if discovery is about to start | 1583 | * Do not start discovery if discovery is about to start |
@@ -1586,53 +1585,51 @@ lpfc_rcv_padisc_npr_node(struct lpfc_hba * phba, | |||
1586 | * here will affect the counting of discovery threads. | 1585 | * here will affect the counting of discovery threads. |
1587 | */ | 1586 | */ |
1588 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && | 1587 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO) && |
1589 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ | 1588 | !(ndlp->nlp_flag & NLP_NPR_2B_DISC)){ |
1590 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { | 1589 | if (ndlp->nlp_flag & NLP_NPR_ADISC) { |
1591 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1590 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1592 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_ADISC_ISSUE); | 1591 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE); |
1593 | lpfc_issue_els_adisc(phba, ndlp, 0); | 1592 | lpfc_issue_els_adisc(vport, ndlp, 0); |
1594 | } else { | 1593 | } else { |
1595 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; | 1594 | ndlp->nlp_prev_state = NLP_STE_NPR_NODE; |
1596 | lpfc_nlp_set_state(phba, ndlp, NLP_STE_PLOGI_ISSUE); | 1595 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE); |
1597 | lpfc_issue_els_plogi(phba, ndlp->nlp_DID, 0); | 1596 | lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0); |
1598 | } | 1597 | } |
1599 | } | 1598 | } |
1600 | return ndlp->nlp_state; | 1599 | return ndlp->nlp_state; |
1601 | } | 1600 | } |
1602 | 1601 | ||
1603 | static uint32_t | 1602 | static uint32_t |
1604 | lpfc_rcv_prlo_npr_node(struct lpfc_hba * phba, | 1603 | lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1605 | struct lpfc_nodelist * ndlp, void *arg, | 1604 | void *arg, uint32_t evt) |
1606 | uint32_t evt) | ||
1607 | { | 1605 | { |
1608 | struct lpfc_iocbq *cmdiocb; | 1606 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1607 | struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; | ||
1609 | 1608 | ||
1610 | cmdiocb = (struct lpfc_iocbq *) arg; | 1609 | spin_lock_irq(shost->host_lock); |
1611 | |||
1612 | spin_lock_irq(phba->host->host_lock); | ||
1613 | ndlp->nlp_flag |= NLP_LOGO_ACC; | 1610 | ndlp->nlp_flag |= NLP_LOGO_ACC; |
1614 | spin_unlock_irq(phba->host->host_lock); | 1611 | spin_unlock_irq(shost->host_lock); |
1615 | 1612 | ||
1616 | lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); | 1613 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); |
1617 | 1614 | ||
1618 | if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) { | 1615 | if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) { |
1619 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); | 1616 | mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1); |
1620 | spin_lock_irq(phba->host->host_lock); | 1617 | spin_lock_irq(shost->host_lock); |
1621 | ndlp->nlp_flag |= NLP_DELAY_TMO; | 1618 | ndlp->nlp_flag |= NLP_DELAY_TMO; |
1622 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1619 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1623 | spin_unlock_irq(phba->host->host_lock); | 1620 | spin_unlock_irq(shost->host_lock); |
1624 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; | 1621 | ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; |
1625 | } else { | 1622 | } else { |
1626 | spin_lock_irq(phba->host->host_lock); | 1623 | spin_lock_irq(shost->host_lock); |
1627 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; | 1624 | ndlp->nlp_flag &= ~NLP_NPR_ADISC; |
1628 | spin_unlock_irq(phba->host->host_lock); | 1625 | spin_unlock_irq(shost->host_lock); |
1629 | } | 1626 | } |
1630 | return ndlp->nlp_state; | 1627 | return ndlp->nlp_state; |
1631 | } | 1628 | } |
1632 | 1629 | ||
1633 | static uint32_t | 1630 | static uint32_t |
1634 | lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, | 1631 | lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1635 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1632 | void *arg, uint32_t evt) |
1636 | { | 1633 | { |
1637 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1634 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1638 | IOCB_t *irsp; | 1635 | IOCB_t *irsp; |
@@ -1642,15 +1639,15 @@ lpfc_cmpl_plogi_npr_node(struct lpfc_hba * phba, | |||
1642 | 1639 | ||
1643 | irsp = &rspiocb->iocb; | 1640 | irsp = &rspiocb->iocb; |
1644 | if (irsp->ulpStatus) { | 1641 | if (irsp->ulpStatus) { |
1645 | lpfc_drop_node(phba, ndlp); | 1642 | lpfc_drop_node(vport, ndlp); |
1646 | return NLP_STE_FREED_NODE; | 1643 | return NLP_STE_FREED_NODE; |
1647 | } | 1644 | } |
1648 | return ndlp->nlp_state; | 1645 | return ndlp->nlp_state; |
1649 | } | 1646 | } |
1650 | 1647 | ||
1651 | static uint32_t | 1648 | static uint32_t |
1652 | lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, | 1649 | lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1653 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1650 | void *arg, uint32_t evt) |
1654 | { | 1651 | { |
1655 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1652 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1656 | IOCB_t *irsp; | 1653 | IOCB_t *irsp; |
@@ -1660,25 +1657,24 @@ lpfc_cmpl_prli_npr_node(struct lpfc_hba * phba, | |||
1660 | 1657 | ||
1661 | irsp = &rspiocb->iocb; | 1658 | irsp = &rspiocb->iocb; |
1662 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { | 1659 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { |
1663 | lpfc_drop_node(phba, ndlp); | 1660 | lpfc_drop_node(vport, ndlp); |
1664 | return NLP_STE_FREED_NODE; | 1661 | return NLP_STE_FREED_NODE; |
1665 | } | 1662 | } |
1666 | return ndlp->nlp_state; | 1663 | return ndlp->nlp_state; |
1667 | } | 1664 | } |
1668 | 1665 | ||
1669 | static uint32_t | 1666 | static uint32_t |
1670 | lpfc_cmpl_logo_npr_node(struct lpfc_hba * phba, | 1667 | lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1671 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1668 | void *arg, uint32_t evt) |
1672 | { | 1669 | { |
1673 | lpfc_unreg_rpi(phba, ndlp); | 1670 | lpfc_unreg_rpi(vport, ndlp); |
1674 | /* This routine does nothing, just return the current state */ | 1671 | /* This routine does nothing, just return the current state */ |
1675 | return ndlp->nlp_state; | 1672 | return ndlp->nlp_state; |
1676 | } | 1673 | } |
1677 | 1674 | ||
1678 | static uint32_t | 1675 | static uint32_t |
1679 | lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, | 1676 | lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1680 | struct lpfc_nodelist * ndlp, void *arg, | 1677 | void *arg, uint32_t evt) |
1681 | uint32_t evt) | ||
1682 | { | 1678 | { |
1683 | struct lpfc_iocbq *cmdiocb, *rspiocb; | 1679 | struct lpfc_iocbq *cmdiocb, *rspiocb; |
1684 | IOCB_t *irsp; | 1680 | IOCB_t *irsp; |
@@ -1688,28 +1684,25 @@ lpfc_cmpl_adisc_npr_node(struct lpfc_hba * phba, | |||
1688 | 1684 | ||
1689 | irsp = &rspiocb->iocb; | 1685 | irsp = &rspiocb->iocb; |
1690 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { | 1686 | if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { |
1691 | lpfc_drop_node(phba, ndlp); | 1687 | lpfc_drop_node(vport, ndlp); |
1692 | return NLP_STE_FREED_NODE; | 1688 | return NLP_STE_FREED_NODE; |
1693 | } | 1689 | } |
1694 | return ndlp->nlp_state; | 1690 | return ndlp->nlp_state; |
1695 | } | 1691 | } |
1696 | 1692 | ||
1697 | static uint32_t | 1693 | static uint32_t |
1698 | lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, | 1694 | lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport, |
1699 | struct lpfc_nodelist * ndlp, void *arg, | 1695 | struct lpfc_nodelist *ndlp, |
1700 | uint32_t evt) | 1696 | void *arg, uint32_t evt) |
1701 | { | 1697 | { |
1702 | LPFC_MBOXQ_t *pmb; | 1698 | LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg; |
1703 | MAILBOX_t *mb; | 1699 | MAILBOX_t *mb = &pmb->mb; |
1704 | |||
1705 | pmb = (LPFC_MBOXQ_t *) arg; | ||
1706 | mb = &pmb->mb; | ||
1707 | 1700 | ||
1708 | if (!mb->mbxStatus) | 1701 | if (!mb->mbxStatus) |
1709 | ndlp->nlp_rpi = mb->un.varWords[0]; | 1702 | ndlp->nlp_rpi = mb->un.varWords[0]; |
1710 | else { | 1703 | else { |
1711 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { | 1704 | if (ndlp->nlp_flag & NLP_NODEV_REMOVE) { |
1712 | lpfc_drop_node(phba, ndlp); | 1705 | lpfc_drop_node(vport, ndlp); |
1713 | return NLP_STE_FREED_NODE; | 1706 | return NLP_STE_FREED_NODE; |
1714 | } | 1707 | } |
1715 | } | 1708 | } |
@@ -1717,28 +1710,32 @@ lpfc_cmpl_reglogin_npr_node(struct lpfc_hba * phba, | |||
1717 | } | 1710 | } |
1718 | 1711 | ||
1719 | static uint32_t | 1712 | static uint32_t |
1720 | lpfc_device_rm_npr_node(struct lpfc_hba * phba, | 1713 | lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1721 | struct lpfc_nodelist * ndlp, void *arg, | 1714 | void *arg, uint32_t evt) |
1722 | uint32_t evt) | ||
1723 | { | 1715 | { |
1716 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | ||
1717 | |||
1724 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { | 1718 | if (ndlp->nlp_flag & NLP_NPR_2B_DISC) { |
1719 | spin_lock_irq(shost->host_lock); | ||
1725 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; | 1720 | ndlp->nlp_flag |= NLP_NODEV_REMOVE; |
1721 | spin_unlock_irq(shost->host_lock); | ||
1726 | return ndlp->nlp_state; | 1722 | return ndlp->nlp_state; |
1727 | } | 1723 | } |
1728 | lpfc_drop_node(phba, ndlp); | 1724 | lpfc_drop_node(vport, ndlp); |
1729 | return NLP_STE_FREED_NODE; | 1725 | return NLP_STE_FREED_NODE; |
1730 | } | 1726 | } |
1731 | 1727 | ||
1732 | static uint32_t | 1728 | static uint32_t |
1733 | lpfc_device_recov_npr_node(struct lpfc_hba * phba, | 1729 | lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1734 | struct lpfc_nodelist * ndlp, void *arg, | 1730 | void *arg, uint32_t evt) |
1735 | uint32_t evt) | ||
1736 | { | 1731 | { |
1737 | spin_lock_irq(phba->host->host_lock); | 1732 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1733 | |||
1734 | spin_lock_irq(shost->host_lock); | ||
1738 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); | 1735 | ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); |
1739 | spin_unlock_irq(phba->host->host_lock); | 1736 | spin_unlock_irq(shost->host_lock); |
1740 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 1737 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1741 | lpfc_cancel_retry_delay_tmo(phba, ndlp); | 1738 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1742 | } | 1739 | } |
1743 | return ndlp->nlp_state; | 1740 | return ndlp->nlp_state; |
1744 | } | 1741 | } |
@@ -1801,7 +1798,7 @@ lpfc_device_recov_npr_node(struct lpfc_hba * phba, | |||
1801 | */ | 1798 | */ |
1802 | 1799 | ||
1803 | static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | 1800 | static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) |
1804 | (struct lpfc_hba *, struct lpfc_nodelist *, void *, uint32_t) = { | 1801 | (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = { |
1805 | /* Action routine Event Current State */ | 1802 | /* Action routine Event Current State */ |
1806 | lpfc_rcv_plogi_unused_node, /* RCV_PLOGI UNUSED_NODE */ | 1803 | lpfc_rcv_plogi_unused_node, /* RCV_PLOGI UNUSED_NODE */ |
1807 | lpfc_rcv_els_unused_node, /* RCV_PRLI */ | 1804 | lpfc_rcv_els_unused_node, /* RCV_PRLI */ |
@@ -1917,11 +1914,12 @@ static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT]) | |||
1917 | }; | 1914 | }; |
1918 | 1915 | ||
1919 | int | 1916 | int |
1920 | lpfc_disc_state_machine(struct lpfc_hba * phba, | 1917 | lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
1921 | struct lpfc_nodelist * ndlp, void *arg, uint32_t evt) | 1918 | void *arg, uint32_t evt) |
1922 | { | 1919 | { |
1920 | struct lpfc_hba *phba = vport->phba; | ||
1923 | uint32_t cur_state, rc; | 1921 | uint32_t cur_state, rc; |
1924 | uint32_t(*func) (struct lpfc_hba *, struct lpfc_nodelist *, void *, | 1922 | uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *, |
1925 | uint32_t); | 1923 | uint32_t); |
1926 | 1924 | ||
1927 | lpfc_nlp_get(ndlp); | 1925 | lpfc_nlp_get(ndlp); |
@@ -1937,7 +1935,7 @@ lpfc_disc_state_machine(struct lpfc_hba * phba, | |||
1937 | evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag); | 1935 | evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag); |
1938 | 1936 | ||
1939 | func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt]; | 1937 | func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt]; |
1940 | rc = (func) (phba, ndlp, arg, evt); | 1938 | rc = (func) (vport, ndlp, arg, evt); |
1941 | 1939 | ||
1942 | /* DSM out state <rc> on NPort <nlp_DID> */ | 1940 | /* DSM out state <rc> on NPort <nlp_DID> */ |
1943 | lpfc_printf_log(phba, | 1941 | lpfc_printf_log(phba, |