diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 98 |
1 files changed, 86 insertions, 12 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 9b4f92941dce..e9845d2ecf10 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -123,6 +123,10 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
123 | "rport devlosscb: sid:x%x did:x%x flg:x%x", | 123 | "rport devlosscb: sid:x%x did:x%x flg:x%x", |
124 | ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); | 124 | ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); |
125 | 125 | ||
126 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, | ||
127 | "3181 dev_loss_callbk x%06x, rport %p flg x%x\n", | ||
128 | ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag); | ||
129 | |||
126 | /* Don't defer this if we are in the process of deleting the vport | 130 | /* Don't defer this if we are in the process of deleting the vport |
127 | * or unloading the driver. The unload will cleanup the node | 131 | * or unloading the driver. The unload will cleanup the node |
128 | * appropriately we just need to cleanup the ndlp rport info here. | 132 | * appropriately we just need to cleanup the ndlp rport info here. |
@@ -142,6 +146,15 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
142 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) | 146 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) |
143 | return; | 147 | return; |
144 | 148 | ||
149 | if (ndlp->nlp_type & NLP_FABRIC) { | ||
150 | |||
151 | /* If the WWPN of the rport and ndlp don't match, ignore it */ | ||
152 | if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn)) { | ||
153 | put_device(&rport->dev); | ||
154 | return; | ||
155 | } | ||
156 | } | ||
157 | |||
145 | evtp = &ndlp->dev_loss_evt; | 158 | evtp = &ndlp->dev_loss_evt; |
146 | 159 | ||
147 | if (!list_empty(&evtp->evt_listp)) | 160 | if (!list_empty(&evtp->evt_listp)) |
@@ -202,6 +215,10 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
202 | "rport devlosstmo:did:x%x type:x%x id:x%x", | 215 | "rport devlosstmo:did:x%x type:x%x id:x%x", |
203 | ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); | 216 | ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); |
204 | 217 | ||
218 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, | ||
219 | "3182 dev_loss_tmo_handler x%06x, rport %p flg x%x\n", | ||
220 | ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag); | ||
221 | |||
205 | /* Don't defer this if we are in the process of deleting the vport | 222 | /* Don't defer this if we are in the process of deleting the vport |
206 | * or unloading the driver. The unload will cleanup the node | 223 | * or unloading the driver. The unload will cleanup the node |
207 | * appropriately we just need to cleanup the ndlp rport info here. | 224 | * appropriately we just need to cleanup the ndlp rport info here. |
@@ -3492,7 +3509,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
3492 | LPFC_MBOXQ_t *pmb = NULL; | 3509 | LPFC_MBOXQ_t *pmb = NULL; |
3493 | MAILBOX_t *mb; | 3510 | MAILBOX_t *mb; |
3494 | struct static_vport_info *vport_info; | 3511 | struct static_vport_info *vport_info; |
3495 | int rc = 0, i; | 3512 | int mbx_wait_rc = 0, i; |
3496 | struct fc_vport_identifiers vport_id; | 3513 | struct fc_vport_identifiers vport_id; |
3497 | struct fc_vport *new_fc_vport; | 3514 | struct fc_vport *new_fc_vport; |
3498 | struct Scsi_Host *shost; | 3515 | struct Scsi_Host *shost; |
@@ -3509,7 +3526,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
3509 | " allocate mailbox memory\n"); | 3526 | " allocate mailbox memory\n"); |
3510 | return; | 3527 | return; |
3511 | } | 3528 | } |
3512 | 3529 | memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); | |
3513 | mb = &pmb->u.mb; | 3530 | mb = &pmb->u.mb; |
3514 | 3531 | ||
3515 | vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL); | 3532 | vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL); |
@@ -3523,24 +3540,31 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
3523 | 3540 | ||
3524 | vport_buff = (uint8_t *) vport_info; | 3541 | vport_buff = (uint8_t *) vport_info; |
3525 | do { | 3542 | do { |
3543 | /* free dma buffer from previous round */ | ||
3544 | if (pmb->context1) { | ||
3545 | mp = (struct lpfc_dmabuf *)pmb->context1; | ||
3546 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
3547 | kfree(mp); | ||
3548 | } | ||
3526 | if (lpfc_dump_static_vport(phba, pmb, offset)) | 3549 | if (lpfc_dump_static_vport(phba, pmb, offset)) |
3527 | goto out; | 3550 | goto out; |
3528 | 3551 | ||
3529 | pmb->vport = phba->pport; | 3552 | pmb->vport = phba->pport; |
3530 | rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO); | 3553 | mbx_wait_rc = lpfc_sli_issue_mbox_wait(phba, pmb, |
3554 | LPFC_MBOX_TMO); | ||
3531 | 3555 | ||
3532 | if ((rc != MBX_SUCCESS) || mb->mbxStatus) { | 3556 | if ((mbx_wait_rc != MBX_SUCCESS) || mb->mbxStatus) { |
3533 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, | 3557 | lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, |
3534 | "0544 lpfc_create_static_vport failed to" | 3558 | "0544 lpfc_create_static_vport failed to" |
3535 | " issue dump mailbox command ret 0x%x " | 3559 | " issue dump mailbox command ret 0x%x " |
3536 | "status 0x%x\n", | 3560 | "status 0x%x\n", |
3537 | rc, mb->mbxStatus); | 3561 | mbx_wait_rc, mb->mbxStatus); |
3538 | goto out; | 3562 | goto out; |
3539 | } | 3563 | } |
3540 | 3564 | ||
3541 | if (phba->sli_rev == LPFC_SLI_REV4) { | 3565 | if (phba->sli_rev == LPFC_SLI_REV4) { |
3542 | byte_count = pmb->u.mqe.un.mb_words[5]; | 3566 | byte_count = pmb->u.mqe.un.mb_words[5]; |
3543 | mp = (struct lpfc_dmabuf *) pmb->context2; | 3567 | mp = (struct lpfc_dmabuf *)pmb->context1; |
3544 | if (byte_count > sizeof(struct static_vport_info) - | 3568 | if (byte_count > sizeof(struct static_vport_info) - |
3545 | offset) | 3569 | offset) |
3546 | byte_count = sizeof(struct static_vport_info) | 3570 | byte_count = sizeof(struct static_vport_info) |
@@ -3604,9 +3628,9 @@ lpfc_create_static_vport(struct lpfc_hba *phba) | |||
3604 | 3628 | ||
3605 | out: | 3629 | out: |
3606 | kfree(vport_info); | 3630 | kfree(vport_info); |
3607 | if (rc != MBX_TIMEOUT) { | 3631 | if (mbx_wait_rc != MBX_TIMEOUT) { |
3608 | if (pmb->context2) { | 3632 | if (pmb->context1) { |
3609 | mp = (struct lpfc_dmabuf *) pmb->context2; | 3633 | mp = (struct lpfc_dmabuf *)pmb->context1; |
3610 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | 3634 | lpfc_mbuf_free(phba, mp->virt, mp->phys); |
3611 | kfree(mp); | 3635 | kfree(mp); |
3612 | } | 3636 | } |
@@ -3834,6 +3858,10 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
3834 | if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) | 3858 | if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) |
3835 | fc_remote_port_rolechg(rport, rport_ids.roles); | 3859 | fc_remote_port_rolechg(rport, rport_ids.roles); |
3836 | 3860 | ||
3861 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, | ||
3862 | "3183 rport register x%06x, rport %p role x%x\n", | ||
3863 | ndlp->nlp_DID, rport, rport_ids.roles); | ||
3864 | |||
3837 | if ((rport->scsi_target_id != -1) && | 3865 | if ((rport->scsi_target_id != -1) && |
3838 | (rport->scsi_target_id < LPFC_MAX_TARGET)) { | 3866 | (rport->scsi_target_id < LPFC_MAX_TARGET)) { |
3839 | ndlp->nlp_sid = rport->scsi_target_id; | 3867 | ndlp->nlp_sid = rport->scsi_target_id; |
@@ -3850,6 +3878,10 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp) | |||
3850 | "rport delete: did:x%x flg:x%x type x%x", | 3878 | "rport delete: did:x%x flg:x%x type x%x", |
3851 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); | 3879 | ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); |
3852 | 3880 | ||
3881 | lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, | ||
3882 | "3184 rport unregister x%06x, rport %p\n", | ||
3883 | ndlp->nlp_DID, rport); | ||
3884 | |||
3853 | fc_remote_port_delete(rport); | 3885 | fc_remote_port_delete(rport); |
3854 | 3886 | ||
3855 | return; | 3887 | return; |
@@ -3964,6 +3996,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state) | |||
3964 | [NLP_STE_ADISC_ISSUE] = "ADISC", | 3996 | [NLP_STE_ADISC_ISSUE] = "ADISC", |
3965 | [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", | 3997 | [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", |
3966 | [NLP_STE_PRLI_ISSUE] = "PRLI", | 3998 | [NLP_STE_PRLI_ISSUE] = "PRLI", |
3999 | [NLP_STE_LOGO_ISSUE] = "LOGO", | ||
3967 | [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", | 4000 | [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", |
3968 | [NLP_STE_MAPPED_NODE] = "MAPPED", | 4001 | [NLP_STE_MAPPED_NODE] = "MAPPED", |
3969 | [NLP_STE_NPR_NODE] = "NPR", | 4002 | [NLP_STE_NPR_NODE] = "NPR", |
@@ -4330,6 +4363,26 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) | |||
4330 | return 0; | 4363 | return 0; |
4331 | } | 4364 | } |
4332 | 4365 | ||
4366 | /** | ||
4367 | * lpfc_nlp_logo_unreg - Unreg mailbox completion handler before LOGO | ||
4368 | * @phba: Pointer to HBA context object. | ||
4369 | * @pmb: Pointer to mailbox object. | ||
4370 | * | ||
4371 | * This function will issue an ELS LOGO command after completing | ||
4372 | * the UNREG_RPI. | ||
4373 | **/ | ||
4374 | void | ||
4375 | lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | ||
4376 | { | ||
4377 | struct lpfc_vport *vport = pmb->vport; | ||
4378 | struct lpfc_nodelist *ndlp; | ||
4379 | |||
4380 | ndlp = (struct lpfc_nodelist *)(pmb->context1); | ||
4381 | if (!ndlp) | ||
4382 | return; | ||
4383 | lpfc_issue_els_logo(vport, ndlp, 0); | ||
4384 | } | ||
4385 | |||
4333 | /* | 4386 | /* |
4334 | * Free rpi associated with LPFC_NODELIST entry. | 4387 | * Free rpi associated with LPFC_NODELIST entry. |
4335 | * This routine is called from lpfc_freenode(), when we are removing | 4388 | * This routine is called from lpfc_freenode(), when we are removing |
@@ -4354,9 +4407,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4354 | rpi = ndlp->nlp_rpi; | 4407 | rpi = ndlp->nlp_rpi; |
4355 | if (phba->sli_rev == LPFC_SLI_REV4) | 4408 | if (phba->sli_rev == LPFC_SLI_REV4) |
4356 | rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; | 4409 | rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; |
4410 | |||
4357 | lpfc_unreg_login(phba, vport->vpi, rpi, mbox); | 4411 | lpfc_unreg_login(phba, vport->vpi, rpi, mbox); |
4358 | mbox->vport = vport; | 4412 | mbox->vport = vport; |
4359 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 4413 | if (ndlp->nlp_flag & NLP_ISSUE_LOGO) { |
4414 | mbox->context1 = ndlp; | ||
4415 | mbox->mbox_cmpl = lpfc_nlp_logo_unreg; | ||
4416 | } else { | ||
4417 | mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | ||
4418 | } | ||
4419 | |||
4360 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4420 | rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
4361 | if (rc == MBX_NOT_FINISHED) | 4421 | if (rc == MBX_NOT_FINISHED) |
4362 | mempool_free(mbox, phba->mbox_mem_pool); | 4422 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -4499,9 +4559,13 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4499 | lpfc_disable_node(vport, ndlp); | 4559 | lpfc_disable_node(vport, ndlp); |
4500 | } | 4560 | } |
4501 | 4561 | ||
4562 | |||
4563 | /* Don't need to clean up REG_LOGIN64 cmds for Default RPI cleanup */ | ||
4564 | |||
4502 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ | 4565 | /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ |
4503 | if ((mb = phba->sli.mbox_active)) { | 4566 | if ((mb = phba->sli.mbox_active)) { |
4504 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && | 4567 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
4568 | !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && | ||
4505 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 4569 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
4506 | mb->context2 = NULL; | 4570 | mb->context2 = NULL; |
4507 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; | 4571 | mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; |
@@ -4512,6 +4576,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4512 | /* Cleanup REG_LOGIN completions which are not yet processed */ | 4576 | /* Cleanup REG_LOGIN completions which are not yet processed */ |
4513 | list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) { | 4577 | list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) { |
4514 | if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) || | 4578 | if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) || |
4579 | (mb->mbox_flag & LPFC_MBX_IMED_UNREG) || | ||
4515 | (ndlp != (struct lpfc_nodelist *) mb->context2)) | 4580 | (ndlp != (struct lpfc_nodelist *) mb->context2)) |
4516 | continue; | 4581 | continue; |
4517 | 4582 | ||
@@ -4521,6 +4586,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4521 | 4586 | ||
4522 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { | 4587 | list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { |
4523 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && | 4588 | if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && |
4589 | !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && | ||
4524 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { | 4590 | (ndlp == (struct lpfc_nodelist *) mb->context2)) { |
4525 | mp = (struct lpfc_dmabuf *) (mb->context1); | 4591 | mp = (struct lpfc_dmabuf *) (mb->context1); |
4526 | if (mp) { | 4592 | if (mp) { |
@@ -4585,7 +4651,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4585 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; | 4651 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; |
4586 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | 4652 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; |
4587 | mbox->vport = vport; | 4653 | mbox->vport = vport; |
4588 | mbox->context2 = NULL; | 4654 | mbox->context2 = ndlp; |
4589 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | 4655 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
4590 | if (rc == MBX_NOT_FINISHED) { | 4656 | if (rc == MBX_NOT_FINISHED) { |
4591 | mempool_free(mbox, phba->mbox_mem_pool); | 4657 | mempool_free(mbox, phba->mbox_mem_pool); |
@@ -5365,9 +5431,17 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) | |||
5365 | struct lpfc_nodelist *ndlp; | 5431 | struct lpfc_nodelist *ndlp; |
5366 | 5432 | ||
5367 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { | 5433 | list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { |
5368 | if (filter(ndlp, param)) | 5434 | if (filter(ndlp, param)) { |
5435 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, | ||
5436 | "3185 FIND node filter %p DID " | ||
5437 | "Data: x%p x%x x%x\n", | ||
5438 | filter, ndlp, ndlp->nlp_DID, | ||
5439 | ndlp->nlp_flag); | ||
5369 | return ndlp; | 5440 | return ndlp; |
5441 | } | ||
5370 | } | 5442 | } |
5443 | lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, | ||
5444 | "3186 FIND node filter %p NOT FOUND.\n", filter); | ||
5371 | return NULL; | 5445 | return NULL; |
5372 | } | 5446 | } |
5373 | 5447 | ||