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 9b4f929..e9845d2 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) "rport devlosscb: sid:x%x did:x%x flg:x%x", ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, + "3181 dev_loss_callbk x%06x, rport %p flg x%x\n", + ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag); + /* Don't defer this if we are in the process of deleting the vport * or unloading the driver. The unload will cleanup the node * appropriately we just need to cleanup the ndlp rport info here. @@ -142,6 +146,15 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) return; + if (ndlp->nlp_type & NLP_FABRIC) { + + /* If the WWPN of the rport and ndlp don't match, ignore it */ + if (rport->port_name != wwn_to_u64(ndlp->nlp_portname.u.wwn)) { + put_device(&rport->dev); + return; + } + } + evtp = &ndlp->dev_loss_evt; if (!list_empty(&evtp->evt_listp)) @@ -202,6 +215,10 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) "rport devlosstmo:did:x%x type:x%x id:x%x", ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, + "3182 dev_loss_tmo_handler x%06x, rport %p flg x%x\n", + ndlp->nlp_DID, ndlp->rport, ndlp->nlp_flag); + /* Don't defer this if we are in the process of deleting the vport * or unloading the driver. The unload will cleanup the node * appropriately we just need to cleanup the ndlp rport info here. @@ -3492,7 +3509,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba) LPFC_MBOXQ_t *pmb = NULL; MAILBOX_t *mb; struct static_vport_info *vport_info; - int rc = 0, i; + int mbx_wait_rc = 0, i; struct fc_vport_identifiers vport_id; struct fc_vport *new_fc_vport; struct Scsi_Host *shost; @@ -3509,7 +3526,7 @@ lpfc_create_static_vport(struct lpfc_hba *phba) " allocate mailbox memory\n"); return; } - + memset(pmb, 0, sizeof(LPFC_MBOXQ_t)); mb = &pmb->u.mb; vport_info = kzalloc(sizeof(struct static_vport_info), GFP_KERNEL); @@ -3523,24 +3540,31 @@ lpfc_create_static_vport(struct lpfc_hba *phba) vport_buff = (uint8_t *) vport_info; do { + /* free dma buffer from previous round */ + if (pmb->context1) { + mp = (struct lpfc_dmabuf *)pmb->context1; + lpfc_mbuf_free(phba, mp->virt, mp->phys); + kfree(mp); + } if (lpfc_dump_static_vport(phba, pmb, offset)) goto out; pmb->vport = phba->pport; - rc = lpfc_sli_issue_mbox_wait(phba, pmb, LPFC_MBOX_TMO); + mbx_wait_rc = lpfc_sli_issue_mbox_wait(phba, pmb, + LPFC_MBOX_TMO); - if ((rc != MBX_SUCCESS) || mb->mbxStatus) { + if ((mbx_wait_rc != MBX_SUCCESS) || mb->mbxStatus) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "0544 lpfc_create_static_vport failed to" " issue dump mailbox command ret 0x%x " "status 0x%x\n", - rc, mb->mbxStatus); + mbx_wait_rc, mb->mbxStatus); goto out; } if (phba->sli_rev == LPFC_SLI_REV4) { byte_count = pmb->u.mqe.un.mb_words[5]; - mp = (struct lpfc_dmabuf *) pmb->context2; + mp = (struct lpfc_dmabuf *)pmb->context1; if (byte_count > sizeof(struct static_vport_info) - offset) byte_count = sizeof(struct static_vport_info) @@ -3604,9 +3628,9 @@ lpfc_create_static_vport(struct lpfc_hba *phba) out: kfree(vport_info); - if (rc != MBX_TIMEOUT) { - if (pmb->context2) { - mp = (struct lpfc_dmabuf *) pmb->context2; + if (mbx_wait_rc != MBX_TIMEOUT) { + if (pmb->context1) { + mp = (struct lpfc_dmabuf *)pmb->context1; lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); } @@ -3834,6 +3858,10 @@ lpfc_register_remote_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) if (rport_ids.roles != FC_RPORT_ROLE_UNKNOWN) fc_remote_port_rolechg(rport, rport_ids.roles); + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, + "3183 rport register x%06x, rport %p role x%x\n", + ndlp->nlp_DID, rport, rport_ids.roles); + if ((rport->scsi_target_id != -1) && (rport->scsi_target_id < LPFC_MAX_TARGET)) { ndlp->nlp_sid = rport->scsi_target_id; @@ -3850,6 +3878,10 @@ lpfc_unregister_remote_port(struct lpfc_nodelist *ndlp) "rport delete: did:x%x flg:x%x type x%x", ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type); + lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_NODE, + "3184 rport unregister x%06x, rport %p\n", + ndlp->nlp_DID, rport); + fc_remote_port_delete(rport); return; @@ -3964,6 +3996,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state) [NLP_STE_ADISC_ISSUE] = "ADISC", [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", [NLP_STE_PRLI_ISSUE] = "PRLI", + [NLP_STE_LOGO_ISSUE] = "LOGO", [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", [NLP_STE_MAPPED_NODE] = "MAPPED", [NLP_STE_NPR_NODE] = "NPR", @@ -4330,6 +4363,26 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) return 0; } +/** + * lpfc_nlp_logo_unreg - Unreg mailbox completion handler before LOGO + * @phba: Pointer to HBA context object. + * @pmb: Pointer to mailbox object. + * + * This function will issue an ELS LOGO command after completing + * the UNREG_RPI. + **/ +void +lpfc_nlp_logo_unreg(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) +{ + struct lpfc_vport *vport = pmb->vport; + struct lpfc_nodelist *ndlp; + + ndlp = (struct lpfc_nodelist *)(pmb->context1); + if (!ndlp) + return; + lpfc_issue_els_logo(vport, ndlp, 0); +} + /* * Free rpi associated with LPFC_NODELIST entry. * 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) rpi = ndlp->nlp_rpi; if (phba->sli_rev == LPFC_SLI_REV4) rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; + lpfc_unreg_login(phba, vport->vpi, rpi, mbox); mbox->vport = vport; - mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + if (ndlp->nlp_flag & NLP_ISSUE_LOGO) { + mbox->context1 = ndlp; + mbox->mbox_cmpl = lpfc_nlp_logo_unreg; + } else { + mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; + } + rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) mempool_free(mbox, phba->mbox_mem_pool); @@ -4499,9 +4559,13 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_disable_node(vport, ndlp); } + + /* Don't need to clean up REG_LOGIN64 cmds for Default RPI cleanup */ + /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ if ((mb = phba->sli.mbox_active)) { if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && + !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && (ndlp == (struct lpfc_nodelist *) mb->context2)) { mb->context2 = NULL; mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; @@ -4512,6 +4576,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) /* Cleanup REG_LOGIN completions which are not yet processed */ list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) { if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) || + (mb->mbox_flag & LPFC_MBX_IMED_UNREG) || (ndlp != (struct lpfc_nodelist *) mb->context2)) continue; @@ -4521,6 +4586,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && + !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && (ndlp == (struct lpfc_nodelist *) mb->context2)) { mp = (struct lpfc_dmabuf *) (mb->context1); if (mp) { @@ -4585,7 +4651,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; mbox->vport = vport; - mbox->context2 = NULL; + mbox->context2 = ndlp; rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { mempool_free(mbox, phba->mbox_mem_pool); @@ -5365,9 +5431,17 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param) struct lpfc_nodelist *ndlp; list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { - if (filter(ndlp, param)) + if (filter(ndlp, param)) { + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "3185 FIND node filter %p DID " + "Data: x%p x%x x%x\n", + filter, ndlp, ndlp->nlp_DID, + ndlp->nlp_flag); return ndlp; + } } + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE, + "3186 FIND node filter %p NOT FOUND.\n", filter); return NULL; } |