Loading drivers/scsi/lpfc/lpfc_crtn.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -457,6 +457,8 @@ int lpfc_sli4_queue_create(struct lpfc_hba *); void lpfc_sli4_queue_destroy(struct lpfc_hba *); void lpfc_sli4_queue_destroy(struct lpfc_hba *); void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *, void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *, struct sli4_wcqe_xri_aborted *); struct sli4_wcqe_xri_aborted *); void lpfc_sli_abts_recover_port(struct lpfc_vport *, struct lpfc_nodelist *); int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t); int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t); int lpfc_issue_reg_vfi(struct lpfc_vport *); int lpfc_issue_reg_vfi(struct lpfc_vport *); int lpfc_issue_unreg_vfi(struct lpfc_vport *); int lpfc_issue_unreg_vfi(struct lpfc_vport *); Loading drivers/scsi/lpfc/lpfc_debugfs.c +10 −2 Original line number Original line Diff line number Diff line Loading @@ -559,6 +559,9 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) case NLP_STE_PRLI_ISSUE: case NLP_STE_PRLI_ISSUE: statep = "PRLI "; statep = "PRLI "; break; break; case NLP_STE_LOGO_ISSUE: statep = "LOGO "; break; case NLP_STE_UNMAPPED_NODE: case NLP_STE_UNMAPPED_NODE: statep = "UNMAP "; statep = "UNMAP "; break; break; Loading @@ -583,8 +586,13 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", *name, *(name+1), *(name+2), *(name+3), *name, *(name+1), *(name+2), *(name+3), *(name+4), *(name+5), *(name+6), *(name+7)); *(name+4), *(name+5), *(name+6), *(name+7)); len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ", if (ndlp->nlp_flag & NLP_RPI_REGISTERED) ndlp->nlp_rpi, ndlp->nlp_flag); len += snprintf(buf+len, size-len, "RPI:%03d ", ndlp->nlp_rpi); else len += snprintf(buf+len, size-len, "RPI:none "); len += snprintf(buf+len, size-len, "flag:x%08x ", ndlp->nlp_flag); if (!ndlp->nlp_type) if (!ndlp->nlp_type) len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); if (ndlp->nlp_type & NLP_FC_NODE) if (ndlp->nlp_type & NLP_FC_NODE) Loading drivers/scsi/lpfc/lpfc_disc.h +6 −4 Original line number Original line Diff line number Diff line Loading @@ -145,6 +145,7 @@ struct lpfc_node_rrq { #define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */ #define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */ #define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */ #define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */ #define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */ #define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */ #define NLP_ISSUE_LOGO 0x00400000 /* waiting to issue a LOGO */ #define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful #define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful ACC */ ACC */ #define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from #define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from Loading Loading @@ -201,10 +202,11 @@ struct lpfc_node_rrq { #define NLP_STE_ADISC_ISSUE 0x2 /* ADISC was sent to NL_PORT */ #define NLP_STE_ADISC_ISSUE 0x2 /* ADISC was sent to NL_PORT */ #define NLP_STE_REG_LOGIN_ISSUE 0x3 /* REG_LOGIN was issued for NL_PORT */ #define NLP_STE_REG_LOGIN_ISSUE 0x3 /* REG_LOGIN was issued for NL_PORT */ #define NLP_STE_PRLI_ISSUE 0x4 /* PRLI was sent to NL_PORT */ #define NLP_STE_PRLI_ISSUE 0x4 /* PRLI was sent to NL_PORT */ #define NLP_STE_UNMAPPED_NODE 0x5 /* PRLI completed from NL_PORT */ #define NLP_STE_LOGO_ISSUE 0x5 /* LOGO was sent to NL_PORT */ #define NLP_STE_MAPPED_NODE 0x6 /* Identified as a FCP Target */ #define NLP_STE_UNMAPPED_NODE 0x6 /* PRLI completed from NL_PORT */ #define NLP_STE_NPR_NODE 0x7 /* NPort disappeared */ #define NLP_STE_MAPPED_NODE 0x7 /* Identified as a FCP Target */ #define NLP_STE_MAX_STATE 0x8 #define NLP_STE_NPR_NODE 0x8 /* NPort disappeared */ #define NLP_STE_MAX_STATE 0x9 #define NLP_STE_FREED_NODE 0xff /* node entry was freed to MEM_NLP */ #define NLP_STE_FREED_NODE 0xff /* node entry was freed to MEM_NLP */ /* For UNUSED_NODE state, the node has just been allocated. /* For UNUSED_NODE state, the node has just been allocated. Loading drivers/scsi/lpfc/lpfc_els.c +115 −22 Original line number Original line Diff line number Diff line Loading @@ -2385,6 +2385,8 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, IOCB_t *irsp; IOCB_t *irsp; struct lpfc_sli *psli; struct lpfc_sli *psli; struct lpfcMboxq *mbox; struct lpfcMboxq *mbox; unsigned long flags; uint32_t skip_recovery = 0; psli = &phba->sli; psli = &phba->sli; /* we pass cmdiocb to state machine which needs rspiocb as well */ /* we pass cmdiocb to state machine which needs rspiocb as well */ Loading @@ -2399,47 +2401,52 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "LOGO cmpl: status:x%x/x%x did:x%x", "LOGO cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID); ndlp->nlp_DID); /* LOGO completes to NPort <nlp_DID> */ /* LOGO completes to NPort <nlp_DID> */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0105 LOGO completes to NPort x%x " "0105 LOGO completes to NPort x%x " "Data: x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x\n", ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, vport->num_disc_nodes); irsp->ulpTimeout, vport->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(vport)) if (lpfc_els_chk_latt(vport)) { skip_recovery = 1; goto out; goto out; } /* Check to see if link went down during discovery */ if (ndlp->nlp_flag & NLP_TARGET_REMOVE) { if (ndlp->nlp_flag & NLP_TARGET_REMOVE) { /* NLP_EVT_DEVICE_RM should unregister the RPI /* NLP_EVT_DEVICE_RM should unregister the RPI * which should abort all outstanding IOs. * which should abort all outstanding IOs. */ */ lpfc_disc_state_machine(vport, ndlp, cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); NLP_EVT_DEVICE_RM); skip_recovery = 1; goto out; goto out; } } if (irsp->ulpStatus) { if (irsp->ulpStatus) { /* Check for retry */ /* Check for retry */ if (lpfc_els_retry(phba, cmdiocb, rspiocb)) if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { /* ELS command is being retried */ /* ELS command is being retried */ skip_recovery = 1; goto out; goto out; } /* LOGO failed */ /* LOGO failed */ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "2756 LOGO failure DID:%06X Status:x%x/x%x\n", "2756 LOGO failure DID:%06X Status:x%x/x%x\n", ndlp->nlp_DID, irsp->ulpStatus, ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4]); irsp->un.ulpWord[4]); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (lpfc_error_lost_link(irsp)) if (lpfc_error_lost_link(irsp)) { skip_recovery = 1; goto out; goto out; else } lpfc_disc_state_machine(vport, ndlp, cmdiocb, } NLP_EVT_CMPL_LOGO); } else /* Call state machine. This will unregister the rpi if needed. */ /* Good status, call state machine. lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); * This will unregister the rpi if needed. */ lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); out: out: lpfc_els_free_iocb(phba, cmdiocb); lpfc_els_free_iocb(phba, cmdiocb); /* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */ /* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */ Loading @@ -2454,8 +2461,29 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == MBX_NOT_FINISHED) { MBX_NOT_FINISHED) { mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool); skip_recovery = 1; } } } } } /* * If the node is a target, the handling attempts to recover the port. * For any other port type, the rpi is unregistered as an implicit * LOGO. */ if ((ndlp->nlp_type & NLP_FCP_TARGET) && (skip_recovery == 0)) { lpfc_cancel_retry_delay_tmo(vport, ndlp); spin_lock_irqsave(shost->host_lock, flags); ndlp->nlp_flag |= NLP_NPR_2B_DISC; spin_unlock_irqrestore(shost->host_lock, flags); lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "3187 LOGO completes to NPort x%x: Start " "Recovery Data: x%x x%x x%x x%x\n", ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, vport->num_disc_nodes); lpfc_disc_start(vport); } } return; return; } } Loading Loading @@ -2519,10 +2547,27 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, "Issue LOGO: did:x%x", "Issue LOGO: did:x%x", ndlp->nlp_DID, 0, 0); ndlp->nlp_DID, 0, 0); /* * If we are issuing a LOGO, we may try to recover the remote NPort * by issuing a PLOGI later. Even though we issue ELS cmds by the * VPI, if we have a valid RPI, and that RPI gets unreg'ed while * that ELS command is in-flight, the HBA returns a IOERR_INVALID_RPI * for that ELS cmd. To avoid this situation, lets get rid of the * RPI right now, before any ELS cmds are sent. */ spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_ISSUE_LOGO; spin_unlock_irq(shost->host_lock); if (lpfc_unreg_rpi(vport, ndlp)) { lpfc_els_free_iocb(phba, elsiocb); return 0; } phba->fc_stat.elsXmitLOGO++; phba->fc_stat.elsXmitLOGO++; elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_LOGO_SND; ndlp->nlp_flag |= NLP_LOGO_SND; ndlp->nlp_flag &= ~NLP_ISSUE_LOGO; spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); Loading Loading @@ -2938,7 +2983,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) case ELS_CMD_LOGO: case ELS_CMD_LOGO: if (!lpfc_issue_els_logo(vport, ndlp, retry)) { if (!lpfc_issue_els_logo(vport, ndlp, retry)) { ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE); } } break; break; case ELS_CMD_FDISC: case ELS_CMD_FDISC: Loading Loading @@ -3291,7 +3336,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return 1; return 1; case ELS_CMD_LOGO: case ELS_CMD_LOGO: ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE); lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry); lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry); return 1; return 1; } } Loading Loading @@ -3551,13 +3596,17 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool); if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { if (ndlp) { if (NLP_CHK_NODE_ACT(ndlp)) { lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp); /* This is the end of the default RPI cleanup logic for this /* This is the end of the default RPI cleanup logic for * ndlp. If no other discovery threads are using this ndlp. * this ndlp. If no other discovery threads are using * we should free all resources associated with it. * this ndlp, free all resources associated with it. */ */ lpfc_nlp_not_used(ndlp); lpfc_nlp_not_used(ndlp); } else { lpfc_drop_node(ndlp->vport, ndlp); } } } return; return; Loading Loading @@ -8003,3 +8052,47 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, spin_unlock_irqrestore(&phba->hbalock, iflag); spin_unlock_irqrestore(&phba->hbalock, iflag); return; return; } } /* lpfc_sli_abts_recover_port - Recover a port that failed a BLS_ABORT req. * @vport: pointer to virtual port object. * @ndlp: nodelist pointer for the impacted node. * * The driver calls this routine in response to an SLI4 XRI ABORT CQE * or an SLI3 ASYNC_STATUS_CN event from the port. For either event, * the driver is required to send a LOGO to the remote node before it * attempts to recover its login to the remote node. */ void lpfc_sli_abts_recover_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { struct Scsi_Host *shost; struct lpfc_hba *phba; unsigned long flags = 0; shost = lpfc_shost_from_vport(vport); phba = vport->phba; if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "3093 No rport recovery needed. " "rport in state 0x%x\n", ndlp->nlp_state); return; } lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "3094 Start rport recovery on shost id 0x%x " "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x " "flags 0x%x\n", shost->host_no, ndlp->nlp_DID, vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state, ndlp->nlp_flag); /* * The rport is not responding. Remove the FCP-2 flag to prevent * an ADISC in the follow-up recovery code. */ spin_lock_irqsave(shost->host_lock, flags); ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; spin_unlock_irqrestore(shost->host_lock, flags); lpfc_issue_els_logo(vport, ndlp, 0); lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE); } drivers/scsi/lpfc/lpfc_hbadisc.c +36 −2 Original line number Original line Diff line number Diff line Loading @@ -3989,6 +3989,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state) [NLP_STE_ADISC_ISSUE] = "ADISC", [NLP_STE_ADISC_ISSUE] = "ADISC", [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", [NLP_STE_PRLI_ISSUE] = "PRLI", [NLP_STE_PRLI_ISSUE] = "PRLI", [NLP_STE_LOGO_ISSUE] = "LOGO", [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", [NLP_STE_MAPPED_NODE] = "MAPPED", [NLP_STE_MAPPED_NODE] = "MAPPED", [NLP_STE_NPR_NODE] = "NPR", [NLP_STE_NPR_NODE] = "NPR", Loading Loading @@ -4355,6 +4356,26 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) return 0; 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. * Free rpi associated with LPFC_NODELIST entry. * This routine is called from lpfc_freenode(), when we are removing * This routine is called from lpfc_freenode(), when we are removing Loading @@ -4379,9 +4400,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) rpi = ndlp->nlp_rpi; rpi = ndlp->nlp_rpi; if (phba->sli_rev == LPFC_SLI_REV4) if (phba->sli_rev == LPFC_SLI_REV4) rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; lpfc_unreg_login(phba, vport->vpi, rpi, mbox); lpfc_unreg_login(phba, vport->vpi, rpi, mbox); mbox->vport = vport; mbox->vport = vport; 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; mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; } rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) if (rc == MBX_NOT_FINISHED) mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool); Loading Loading @@ -4524,9 +4552,13 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_disable_node(vport, 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 */ /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ if ((mb = phba->sli.mbox_active)) { if ((mb = phba->sli.mbox_active)) { if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && (ndlp == (struct lpfc_nodelist *) mb->context2)) { (ndlp == (struct lpfc_nodelist *) mb->context2)) { mb->context2 = NULL; mb->context2 = NULL; mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; Loading @@ -4537,6 +4569,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) /* Cleanup REG_LOGIN completions which are not yet processed */ /* Cleanup REG_LOGIN completions which are not yet processed */ list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) { list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) { if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) || if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) || (mb->mbox_flag & LPFC_MBX_IMED_UNREG) || (ndlp != (struct lpfc_nodelist *) mb->context2)) (ndlp != (struct lpfc_nodelist *) mb->context2)) continue; continue; Loading @@ -4546,6 +4579,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && (ndlp == (struct lpfc_nodelist *) mb->context2)) { (ndlp == (struct lpfc_nodelist *) mb->context2)) { mp = (struct lpfc_dmabuf *) (mb->context1); mp = (struct lpfc_dmabuf *) (mb->context1); if (mp) { if (mp) { Loading Loading @@ -4610,7 +4644,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; mbox->vport = vport; mbox->vport = vport; mbox->context2 = NULL; mbox->context2 = ndlp; rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { if (rc == MBX_NOT_FINISHED) { mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool); Loading Loading
drivers/scsi/lpfc/lpfc_crtn.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -457,6 +457,8 @@ int lpfc_sli4_queue_create(struct lpfc_hba *); void lpfc_sli4_queue_destroy(struct lpfc_hba *); void lpfc_sli4_queue_destroy(struct lpfc_hba *); void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *, void lpfc_sli4_abts_err_handler(struct lpfc_hba *, struct lpfc_nodelist *, struct sli4_wcqe_xri_aborted *); struct sli4_wcqe_xri_aborted *); void lpfc_sli_abts_recover_port(struct lpfc_vport *, struct lpfc_nodelist *); int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t); int lpfc_hba_init_link_fc_topology(struct lpfc_hba *, uint32_t, uint32_t); int lpfc_issue_reg_vfi(struct lpfc_vport *); int lpfc_issue_reg_vfi(struct lpfc_vport *); int lpfc_issue_unreg_vfi(struct lpfc_vport *); int lpfc_issue_unreg_vfi(struct lpfc_vport *); Loading
drivers/scsi/lpfc/lpfc_debugfs.c +10 −2 Original line number Original line Diff line number Diff line Loading @@ -559,6 +559,9 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) case NLP_STE_PRLI_ISSUE: case NLP_STE_PRLI_ISSUE: statep = "PRLI "; statep = "PRLI "; break; break; case NLP_STE_LOGO_ISSUE: statep = "LOGO "; break; case NLP_STE_UNMAPPED_NODE: case NLP_STE_UNMAPPED_NODE: statep = "UNMAP "; statep = "UNMAP "; break; break; Loading @@ -583,8 +586,13 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size) "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", "WWNN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", *name, *(name+1), *(name+2), *(name+3), *name, *(name+1), *(name+2), *(name+3), *(name+4), *(name+5), *(name+6), *(name+7)); *(name+4), *(name+5), *(name+6), *(name+7)); len += snprintf(buf+len, size-len, "RPI:%03d flag:x%08x ", if (ndlp->nlp_flag & NLP_RPI_REGISTERED) ndlp->nlp_rpi, ndlp->nlp_flag); len += snprintf(buf+len, size-len, "RPI:%03d ", ndlp->nlp_rpi); else len += snprintf(buf+len, size-len, "RPI:none "); len += snprintf(buf+len, size-len, "flag:x%08x ", ndlp->nlp_flag); if (!ndlp->nlp_type) if (!ndlp->nlp_type) len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); len += snprintf(buf+len, size-len, "UNKNOWN_TYPE "); if (ndlp->nlp_type & NLP_FC_NODE) if (ndlp->nlp_type & NLP_FC_NODE) Loading
drivers/scsi/lpfc/lpfc_disc.h +6 −4 Original line number Original line Diff line number Diff line Loading @@ -145,6 +145,7 @@ struct lpfc_node_rrq { #define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */ #define NLP_RCV_PLOGI 0x00080000 /* Rcv'ed PLOGI from remote system */ #define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */ #define NLP_LOGO_ACC 0x00100000 /* Process LOGO after ACC completes */ #define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */ #define NLP_TGT_NO_SCSIID 0x00200000 /* good PRLI but no binding for scsid */ #define NLP_ISSUE_LOGO 0x00400000 /* waiting to issue a LOGO */ #define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful #define NLP_ACC_REGLOGIN 0x01000000 /* Issue Reg Login after successful ACC */ ACC */ #define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from #define NLP_NPR_ADISC 0x02000000 /* Issue ADISC when dq'ed from Loading Loading @@ -201,10 +202,11 @@ struct lpfc_node_rrq { #define NLP_STE_ADISC_ISSUE 0x2 /* ADISC was sent to NL_PORT */ #define NLP_STE_ADISC_ISSUE 0x2 /* ADISC was sent to NL_PORT */ #define NLP_STE_REG_LOGIN_ISSUE 0x3 /* REG_LOGIN was issued for NL_PORT */ #define NLP_STE_REG_LOGIN_ISSUE 0x3 /* REG_LOGIN was issued for NL_PORT */ #define NLP_STE_PRLI_ISSUE 0x4 /* PRLI was sent to NL_PORT */ #define NLP_STE_PRLI_ISSUE 0x4 /* PRLI was sent to NL_PORT */ #define NLP_STE_UNMAPPED_NODE 0x5 /* PRLI completed from NL_PORT */ #define NLP_STE_LOGO_ISSUE 0x5 /* LOGO was sent to NL_PORT */ #define NLP_STE_MAPPED_NODE 0x6 /* Identified as a FCP Target */ #define NLP_STE_UNMAPPED_NODE 0x6 /* PRLI completed from NL_PORT */ #define NLP_STE_NPR_NODE 0x7 /* NPort disappeared */ #define NLP_STE_MAPPED_NODE 0x7 /* Identified as a FCP Target */ #define NLP_STE_MAX_STATE 0x8 #define NLP_STE_NPR_NODE 0x8 /* NPort disappeared */ #define NLP_STE_MAX_STATE 0x9 #define NLP_STE_FREED_NODE 0xff /* node entry was freed to MEM_NLP */ #define NLP_STE_FREED_NODE 0xff /* node entry was freed to MEM_NLP */ /* For UNUSED_NODE state, the node has just been allocated. /* For UNUSED_NODE state, the node has just been allocated. Loading
drivers/scsi/lpfc/lpfc_els.c +115 −22 Original line number Original line Diff line number Diff line Loading @@ -2385,6 +2385,8 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, IOCB_t *irsp; IOCB_t *irsp; struct lpfc_sli *psli; struct lpfc_sli *psli; struct lpfcMboxq *mbox; struct lpfcMboxq *mbox; unsigned long flags; uint32_t skip_recovery = 0; psli = &phba->sli; psli = &phba->sli; /* we pass cmdiocb to state machine which needs rspiocb as well */ /* we pass cmdiocb to state machine which needs rspiocb as well */ Loading @@ -2399,47 +2401,52 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, "LOGO cmpl: status:x%x/x%x did:x%x", "LOGO cmpl: status:x%x/x%x did:x%x", irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID); ndlp->nlp_DID); /* LOGO completes to NPort <nlp_DID> */ /* LOGO completes to NPort <nlp_DID> */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0105 LOGO completes to NPort x%x " "0105 LOGO completes to NPort x%x " "Data: x%x x%x x%x x%x\n", "Data: x%x x%x x%x x%x\n", ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, vport->num_disc_nodes); irsp->ulpTimeout, vport->num_disc_nodes); /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(vport)) if (lpfc_els_chk_latt(vport)) { skip_recovery = 1; goto out; goto out; } /* Check to see if link went down during discovery */ if (ndlp->nlp_flag & NLP_TARGET_REMOVE) { if (ndlp->nlp_flag & NLP_TARGET_REMOVE) { /* NLP_EVT_DEVICE_RM should unregister the RPI /* NLP_EVT_DEVICE_RM should unregister the RPI * which should abort all outstanding IOs. * which should abort all outstanding IOs. */ */ lpfc_disc_state_machine(vport, ndlp, cmdiocb, lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_DEVICE_RM); NLP_EVT_DEVICE_RM); skip_recovery = 1; goto out; goto out; } } if (irsp->ulpStatus) { if (irsp->ulpStatus) { /* Check for retry */ /* Check for retry */ if (lpfc_els_retry(phba, cmdiocb, rspiocb)) if (lpfc_els_retry(phba, cmdiocb, rspiocb)) { /* ELS command is being retried */ /* ELS command is being retried */ skip_recovery = 1; goto out; goto out; } /* LOGO failed */ /* LOGO failed */ lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, "2756 LOGO failure DID:%06X Status:x%x/x%x\n", "2756 LOGO failure DID:%06X Status:x%x/x%x\n", ndlp->nlp_DID, irsp->ulpStatus, ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4]); irsp->un.ulpWord[4]); /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ if (lpfc_error_lost_link(irsp)) if (lpfc_error_lost_link(irsp)) { skip_recovery = 1; goto out; goto out; else } lpfc_disc_state_machine(vport, ndlp, cmdiocb, } NLP_EVT_CMPL_LOGO); } else /* Call state machine. This will unregister the rpi if needed. */ /* Good status, call state machine. lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); * This will unregister the rpi if needed. */ lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO); out: out: lpfc_els_free_iocb(phba, cmdiocb); lpfc_els_free_iocb(phba, cmdiocb); /* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */ /* If we are in pt2pt mode, we could rcv new S_ID on PLOGI */ Loading @@ -2454,8 +2461,29 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == MBX_NOT_FINISHED) { MBX_NOT_FINISHED) { mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool); skip_recovery = 1; } } } } } /* * If the node is a target, the handling attempts to recover the port. * For any other port type, the rpi is unregistered as an implicit * LOGO. */ if ((ndlp->nlp_type & NLP_FCP_TARGET) && (skip_recovery == 0)) { lpfc_cancel_retry_delay_tmo(vport, ndlp); spin_lock_irqsave(shost->host_lock, flags); ndlp->nlp_flag |= NLP_NPR_2B_DISC; spin_unlock_irqrestore(shost->host_lock, flags); lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "3187 LOGO completes to NPort x%x: Start " "Recovery Data: x%x x%x x%x x%x\n", ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4], irsp->ulpTimeout, vport->num_disc_nodes); lpfc_disc_start(vport); } } return; return; } } Loading Loading @@ -2519,10 +2547,27 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, "Issue LOGO: did:x%x", "Issue LOGO: did:x%x", ndlp->nlp_DID, 0, 0); ndlp->nlp_DID, 0, 0); /* * If we are issuing a LOGO, we may try to recover the remote NPort * by issuing a PLOGI later. Even though we issue ELS cmds by the * VPI, if we have a valid RPI, and that RPI gets unreg'ed while * that ELS command is in-flight, the HBA returns a IOERR_INVALID_RPI * for that ELS cmd. To avoid this situation, lets get rid of the * RPI right now, before any ELS cmds are sent. */ spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_ISSUE_LOGO; spin_unlock_irq(shost->host_lock); if (lpfc_unreg_rpi(vport, ndlp)) { lpfc_els_free_iocb(phba, elsiocb); return 0; } phba->fc_stat.elsXmitLOGO++; phba->fc_stat.elsXmitLOGO++; elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock); ndlp->nlp_flag |= NLP_LOGO_SND; ndlp->nlp_flag |= NLP_LOGO_SND; ndlp->nlp_flag &= ~NLP_ISSUE_LOGO; spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0); Loading Loading @@ -2938,7 +2983,7 @@ lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp) case ELS_CMD_LOGO: case ELS_CMD_LOGO: if (!lpfc_issue_els_logo(vport, ndlp, retry)) { if (!lpfc_issue_els_logo(vport, ndlp, retry)) { ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE); } } break; break; case ELS_CMD_FDISC: case ELS_CMD_FDISC: Loading Loading @@ -3291,7 +3336,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, return 1; return 1; case ELS_CMD_LOGO: case ELS_CMD_LOGO: ndlp->nlp_prev_state = ndlp->nlp_state; ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE); lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry); lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry); return 1; return 1; } } Loading Loading @@ -3551,13 +3596,17 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool); if (ndlp && NLP_CHK_NODE_ACT(ndlp)) { if (ndlp) { if (NLP_CHK_NODE_ACT(ndlp)) { lpfc_nlp_put(ndlp); lpfc_nlp_put(ndlp); /* This is the end of the default RPI cleanup logic for this /* This is the end of the default RPI cleanup logic for * ndlp. If no other discovery threads are using this ndlp. * this ndlp. If no other discovery threads are using * we should free all resources associated with it. * this ndlp, free all resources associated with it. */ */ lpfc_nlp_not_used(ndlp); lpfc_nlp_not_used(ndlp); } else { lpfc_drop_node(ndlp->vport, ndlp); } } } return; return; Loading Loading @@ -8003,3 +8052,47 @@ lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba, spin_unlock_irqrestore(&phba->hbalock, iflag); spin_unlock_irqrestore(&phba->hbalock, iflag); return; return; } } /* lpfc_sli_abts_recover_port - Recover a port that failed a BLS_ABORT req. * @vport: pointer to virtual port object. * @ndlp: nodelist pointer for the impacted node. * * The driver calls this routine in response to an SLI4 XRI ABORT CQE * or an SLI3 ASYNC_STATUS_CN event from the port. For either event, * the driver is required to send a LOGO to the remote node before it * attempts to recover its login to the remote node. */ void lpfc_sli_abts_recover_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) { struct Scsi_Host *shost; struct lpfc_hba *phba; unsigned long flags = 0; shost = lpfc_shost_from_vport(vport); phba = vport->phba; if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) { lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "3093 No rport recovery needed. " "rport in state 0x%x\n", ndlp->nlp_state); return; } lpfc_printf_log(phba, KERN_INFO, LOG_SLI, "3094 Start rport recovery on shost id 0x%x " "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x " "flags 0x%x\n", shost->host_no, ndlp->nlp_DID, vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state, ndlp->nlp_flag); /* * The rport is not responding. Remove the FCP-2 flag to prevent * an ADISC in the follow-up recovery code. */ spin_lock_irqsave(shost->host_lock, flags); ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE; spin_unlock_irqrestore(shost->host_lock, flags); lpfc_issue_els_logo(vport, ndlp, 0); lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE); }
drivers/scsi/lpfc/lpfc_hbadisc.c +36 −2 Original line number Original line Diff line number Diff line Loading @@ -3989,6 +3989,7 @@ lpfc_nlp_state_name(char *buffer, size_t size, int state) [NLP_STE_ADISC_ISSUE] = "ADISC", [NLP_STE_ADISC_ISSUE] = "ADISC", [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", [NLP_STE_REG_LOGIN_ISSUE] = "REGLOGIN", [NLP_STE_PRLI_ISSUE] = "PRLI", [NLP_STE_PRLI_ISSUE] = "PRLI", [NLP_STE_LOGO_ISSUE] = "LOGO", [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", [NLP_STE_UNMAPPED_NODE] = "UNMAPPED", [NLP_STE_MAPPED_NODE] = "MAPPED", [NLP_STE_MAPPED_NODE] = "MAPPED", [NLP_STE_NPR_NODE] = "NPR", [NLP_STE_NPR_NODE] = "NPR", Loading Loading @@ -4355,6 +4356,26 @@ lpfc_no_rpi(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) return 0; 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. * Free rpi associated with LPFC_NODELIST entry. * This routine is called from lpfc_freenode(), when we are removing * This routine is called from lpfc_freenode(), when we are removing Loading @@ -4379,9 +4400,16 @@ lpfc_unreg_rpi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) rpi = ndlp->nlp_rpi; rpi = ndlp->nlp_rpi; if (phba->sli_rev == LPFC_SLI_REV4) if (phba->sli_rev == LPFC_SLI_REV4) rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]; lpfc_unreg_login(phba, vport->vpi, rpi, mbox); lpfc_unreg_login(phba, vport->vpi, rpi, mbox); mbox->vport = vport; mbox->vport = vport; 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; mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl; } rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) if (rc == MBX_NOT_FINISHED) mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool); Loading Loading @@ -4524,9 +4552,13 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) lpfc_disable_node(vport, 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 */ /* cleanup any ndlp on mbox q waiting for reglogin cmpl */ if ((mb = phba->sli.mbox_active)) { if ((mb = phba->sli.mbox_active)) { if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && (ndlp == (struct lpfc_nodelist *) mb->context2)) { (ndlp == (struct lpfc_nodelist *) mb->context2)) { mb->context2 = NULL; mb->context2 = NULL; mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl; Loading @@ -4537,6 +4569,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) /* Cleanup REG_LOGIN completions which are not yet processed */ /* Cleanup REG_LOGIN completions which are not yet processed */ list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) { list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) { if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) || if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) || (mb->mbox_flag & LPFC_MBX_IMED_UNREG) || (ndlp != (struct lpfc_nodelist *) mb->context2)) (ndlp != (struct lpfc_nodelist *) mb->context2)) continue; continue; Loading @@ -4546,6 +4579,7 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && !(mb->mbox_flag & LPFC_MBX_IMED_UNREG) && (ndlp == (struct lpfc_nodelist *) mb->context2)) { (ndlp == (struct lpfc_nodelist *) mb->context2)) { mp = (struct lpfc_dmabuf *) (mb->context1); mp = (struct lpfc_dmabuf *) (mb->context1); if (mp) { if (mp) { Loading Loading @@ -4610,7 +4644,7 @@ lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; mbox->vport = vport; mbox->vport = vport; mbox->context2 = NULL; mbox->context2 = ndlp; rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); if (rc == MBX_NOT_FINISHED) { if (rc == MBX_NOT_FINISHED) { mempool_free(mbox, phba->mbox_mem_pool); mempool_free(mbox, phba->mbox_mem_pool); Loading