diff options
author | James Smart <James.Smart@Emulex.Com> | 2007-06-17 20:56:36 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-06-17 23:05:45 -0400 |
commit | 2e0fef85e098f6794956b8b80b111179fbb4cbb7 (patch) | |
tree | f632090be67f95e9a637eeb044938ba1591e848f /drivers/scsi/lpfc/lpfc_nportdisc.c | |
parent | 4c2baaaf2ba4875d1d2d59b3b3e1216d3277b17a (diff) |
[SCSI] lpfc: NPIV: split ports
The driver is reorganized to separate the handling of the adapter from
the handling of the FC port. Adapter handling includes submissions of
command requests, receiving responses, and managing adapter resources.
The FC port includes the discovery engine, login handling, and the
mapping of a Scsi_Host on the "port". Although not a large functional
change, as it touches core structures and functions, resulting in a
large text delta.
Signed-off-by: James Smart <James.Smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
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, |