Loading drivers/scsi/lpfc/lpfc_crtn.h +2 −1 Original line number Diff line number Diff line Loading @@ -51,8 +51,9 @@ int lpfc_can_disctmo(struct lpfc_hba *); int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *); int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *, struct lpfc_nodelist *); int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *); void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); int lpfc_nlp_put(struct lpfc_nodelist *); struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); void lpfc_disc_list_loopmap(struct lpfc_hba *); void lpfc_disc_start(struct lpfc_hba *); Loading drivers/scsi/lpfc/lpfc_disc.h +1 −2 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ struct lpfc_nodelist { uint16_t nlp_maxframe; /* Max RCV frame size */ uint8_t nlp_class_sup; /* Supported Classes */ uint8_t nlp_retry; /* used for ELS retries */ uint8_t nlp_disc_refcnt; /* used for DSM */ uint8_t nlp_fcp_info; /* class info, bits 0-3 */ #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ Loading @@ -80,6 +79,7 @@ struct lpfc_nodelist { struct lpfc_work_evt els_retry_evt; unsigned long last_ramp_up_time; /* jiffy of last ramp up */ unsigned long last_q_full_time; /* jiffy of last queue full */ struct kref kref; }; /* Defines for nlp_flag (uint32) */ Loading Loading @@ -107,7 +107,6 @@ struct lpfc_nodelist { ACC */ #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from NPR list */ #define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */ #define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ /* Defines for list searchs */ Loading drivers/scsi/lpfc/lpfc_els.c +59 −48 Original line number Diff line number Diff line Loading @@ -209,9 +209,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, } /* Save for completion so we can release these resources */ elsiocb->context1 = (uint8_t *) ndlp; elsiocb->context2 = (uint8_t *) pcmd; elsiocb->context3 = (uint8_t *) pbuflist; elsiocb->context1 = lpfc_nlp_get(ndlp); elsiocb->context2 = pcmd; elsiocb->context3 = pbuflist; elsiocb->retry = retry; elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT; Loading Loading @@ -305,7 +305,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, goto fail_free_mbox; mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; mbox->context2 = ndlp; mbox->context2 = lpfc_nlp_get(ndlp); rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); if (rc == MBX_NOT_FINISHED) Loading @@ -314,6 +314,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, return 0; fail_issue_reg_login: lpfc_nlp_put(ndlp); mp = (struct lpfc_dmabuf *) mbox->context1; lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading Loading @@ -369,7 +370,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto fail; } mempool_free(ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, PT2PT_RemoteID); if (!ndlp) { Loading @@ -392,7 +393,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, ndlp->nlp_flag |= NLP_NPR_2B_DISC; } else { /* This side will wait for the PLOGI */ mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); } spin_lock_irq(phba->host->host_lock); Loading @@ -407,8 +408,8 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, } static void lpfc_cmpl_els_flogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { IOCB_t *irsp = &rspiocb->iocb; struct lpfc_nodelist *ndlp = cmdiocb->context1; Loading @@ -418,7 +419,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(phba)) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); goto out; } Loading @@ -433,13 +434,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); spin_unlock_irq(phba->host->host_lock); /* If private loop, then allow max outstandting els to be /* If private loop, then allow max outstanding els to be * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no * alpa map would take too long otherwise. */ if (phba->alpa_map[0] == 0) { phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; } /* FLOGI failure */ Loading Loading @@ -484,7 +484,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, } flogifail: lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && Loading Loading @@ -608,7 +608,7 @@ lpfc_initial_flogi(struct lpfc_hba * phba) lpfc_dequeue_node(phba, ndlp); } if (lpfc_issue_els_flogi(phba, ndlp, 0)) { mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); } return 1; } Loading Loading @@ -1334,7 +1334,7 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_SCR); if (!elsiocb) { mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 1; } Loading @@ -1353,12 +1353,12 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_lock_irq(phba->host->host_lock); if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); return 1; } spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -1387,7 +1387,7 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_RNID); if (!elsiocb) { mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 1; } Loading Loading @@ -1420,12 +1420,12 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_lock_irq(phba->host->host_lock); if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); return 1; } spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -1772,6 +1772,10 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb) { struct lpfc_dmabuf *buf_ptr, *buf_ptr1; if (elsiocb->context1) { lpfc_nlp_put(elsiocb->context1); elsiocb->context1 = NULL; } /* context2 = cmd, context2->next = rsp, context3 = bpl */ if (elsiocb->context2) { buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; Loading Loading @@ -1844,7 +1848,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, /* Check to see if link went down during discovery */ if ((lpfc_els_chk_latt(phba)) || !ndlp) { if (lpfc_els_chk_latt(phba) || !ndlp) { if (mbox) { mp = (struct lpfc_dmabuf *) mbox->context1; if (mp) { Loading @@ -1871,7 +1875,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { lpfc_unreg_rpi(phba, ndlp); mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->context2 = ndlp; mbox->context2 = lpfc_nlp_get(ndlp); ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); if (lpfc_sli_issue_mbox(phba, mbox, Loading @@ -1879,6 +1883,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, != MBX_NOT_FINISHED) { goto out; } lpfc_nlp_put(ndlp); /* NOTE: we should have messages for unsuccessful reglogin */ } else { Loading Loading @@ -1983,8 +1988,10 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, return 1; } if (newnode) if (newnode) { lpfc_nlp_put(ndlp); elsiocb->context1 = NULL; } /* Xmit ELS ACC response tag <ulpIoTag> */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, Loading Loading @@ -2201,8 +2208,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, } static int lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, uint8_t format, lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) { RNID *rn; Loading Loading @@ -2270,6 +2276,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, phba->fc_stat.elsXmitACC++; elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; lpfc_nlp_put(ndlp); elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, * it could be freed */ Loading Loading @@ -2814,6 +2821,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mempool_free(pmb, phba->mbox_mem_pool); elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, ndlp->nlp_DID, ELS_CMD_ACC); lpfc_nlp_put(ndlp); if (!elsiocb) return; Loading Loading @@ -2890,13 +2898,14 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, lpfc_read_lnk_stat(phba, mbox); mbox->context1 = (void *)((unsigned long)cmdiocb->iocb.ulpContext); mbox->context2 = ndlp; mbox->context2 = lpfc_nlp_get(ndlp); mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; if (lpfc_sli_issue_mbox (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { /* Mbox completion will send ELS Response */ return 0; } lpfc_nlp_put(ndlp); mempool_free(mbox, phba->mbox_mem_pool); } } Loading Loading @@ -3284,11 +3293,10 @@ void lpfc_els_flush_cmd(struct lpfc_hba *phba) { LIST_HEAD(completions); struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; struct lpfc_iocbq *tmp_iocb, *piocb; IOCB_t *cmd = NULL; pring = &phba->sli.ring[LPFC_ELS_RING]; spin_lock_irq(phba->host->host_lock); list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { cmd = &piocb->iocb; Loading @@ -3298,12 +3306,11 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) } /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */ if ((cmd->ulpCommand == CMD_QUE_RING_BUF_CN) || (cmd->ulpCommand == CMD_QUE_RING_BUF64_CN) || (cmd->ulpCommand == CMD_CLOSE_XRI_CN) || (cmd->ulpCommand == CMD_ABORT_XRI_CN)) { if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN || cmd->ulpCommand == CMD_QUE_RING_BUF64_CN || cmd->ulpCommand == CMD_CLOSE_XRI_CN || cmd->ulpCommand == CMD_ABORT_XRI_CN) continue; } list_move_tail(&piocb->list, &completions); pring->txq_cnt--; Loading Loading @@ -3422,7 +3429,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, } phba->fc_stat.elsRcvFrame++; elsiocb->context1 = ndlp; if (elsiocb->context1) lpfc_nlp_put(elsiocb->context1); elsiocb->context1 = lpfc_nlp_get(ndlp); elsiocb->context2 = mp; if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { Loading Loading @@ -3553,6 +3562,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp); } lpfc_nlp_put(elsiocb->context1); elsiocb->context1 = NULL; if (elsiocb->context2) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading drivers/scsi/lpfc/lpfc_hbadisc.c +72 −35 Original line number Diff line number Diff line Loading @@ -158,6 +158,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) else { rdata->pnode = NULL; ndlp->rport = NULL; lpfc_nlp_put(ndlp); put_device(&rport->dev); } return; Loading Loading @@ -960,6 +962,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free( pmb, phba->mbox_mem_pool); lpfc_nlp_put(ndlp); return; } Loading @@ -986,11 +989,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ndlp = (struct lpfc_nodelist *) pmb->context2; mp = (struct lpfc_dmabuf *) (pmb->context1); pmb->context1 = NULL; pmb->context2 = NULL; if (mb->mbxStatus) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(phba); Loading @@ -1000,12 +1006,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } pmb->context1 = NULL; ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { /* This NPort has been assigned an NPort_ID by the fabric as a * result of the completed fabric login. Issue a State Change Loading Loading @@ -1075,6 +1081,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mp = (struct lpfc_dmabuf *) (pmb->context1); if (mb->mbxStatus) { lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); Loading Loading @@ -1110,6 +1117,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_disc_start(phba); } lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free( pmb, phba->mbox_mem_pool); Loading @@ -1118,8 +1126,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) } static void lpfc_register_remote_port(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct fc_rport *rport; struct lpfc_rport_data *rdata; Loading @@ -1131,8 +1138,19 @@ lpfc_register_remote_port(struct lpfc_hba * phba, rport_ids.port_id = ndlp->nlp_DID; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; /* * We leave our node pointer in rport->dd_data when we unregister a * FCP target port. But fc_remote_port_add zeros the space to which * rport->dd_data points. So, if we're reusing a previously * registered port, drop the reference that we took the last time we * registered the port. */ if (ndlp->rport && ndlp->rport->dd_data && *(struct lpfc_rport_data **) ndlp->rport->dd_data) { lpfc_nlp_put(ndlp); } ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); if (!rport) { if (!rport || !get_device(&rport->dev)) { dev_printk(KERN_WARNING, &phba->pcidev->dev, "Warning: fc_remote_port_add failed\n"); return; Loading @@ -1142,7 +1160,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, rport->maxframe_size = ndlp->nlp_maxframe; rport->supported_classes = ndlp->nlp_class_sup; rdata = rport->dd_data; rdata->pnode = ndlp; rdata->pnode = lpfc_nlp_get(ndlp); if (ndlp->nlp_type & NLP_FCP_TARGET) rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; Loading @@ -1162,8 +1180,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, } static void lpfc_unregister_remote_port(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct fc_rport *rport = ndlp->rport; struct lpfc_rport_data *rdata = rport->dd_data; Loading @@ -1171,6 +1188,8 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba, if (rport->scsi_target_id == -1) { ndlp->rport = NULL; rdata->pnode = NULL; lpfc_nlp_put(ndlp); put_device(&rport->dev); } fc_remote_port_delete(rport); Loading Loading @@ -1416,7 +1435,7 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) lpfc_nlp_counters(phba, ndlp->nlp_state, -1); lpfc_delink_node(phba, ndlp); spin_unlock_irq(phba->host->host_lock); lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } /* Loading Loading @@ -1654,6 +1673,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) } list_del(&mb->list); mempool_free(mb, phba->mbox_mem_pool); lpfc_nlp_put(ndlp); } } spin_unlock_irq(phba->host->host_lock); Loading @@ -1679,7 +1699,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) * If we are in the middle of using the nlp in the discovery state * machine, defer the free till we reach the end of the state machine. */ int static void lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct lpfc_rport_data *rdata; Loading @@ -1688,22 +1708,14 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_cancel_retry_delay_tmo(phba, ndlp); } if (ndlp->nlp_disc_refcnt) { spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_DELAY_REMOVE; spin_unlock_irq(phba->host->host_lock); } else { lpfc_freenode(phba, ndlp); if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { put_device(&ndlp->rport->dev); rdata = ndlp->rport->dd_data; rdata->pnode = NULL; ndlp->rport = NULL; } mempool_free( ndlp, phba->nlp_mem_pool); } return 0; } static int Loading Loading @@ -2069,14 +2081,14 @@ lpfc_disc_flush_list(struct lpfc_hba * phba) list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, nlp_listp) { lpfc_free_tx(phba, ndlp); lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } } if (phba->fc_adisc_cnt) { list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, nlp_listp) { lpfc_free_tx(phba, ndlp); lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } } return; Loading Loading @@ -2195,7 +2207,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) /* Next look for NameServer ndlp */ ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); if (ndlp) lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); /* Start discovery */ lpfc_disc_start(phba); break; Loading Loading @@ -2373,6 +2385,8 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); } /* Mailbox took a reference to the node */ lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); Loading Loading @@ -2460,8 +2474,7 @@ lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, } void lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) { memset(ndlp, 0, sizeof (struct lpfc_nodelist)); INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); Loading @@ -2471,5 +2484,29 @@ lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ndlp->nlp_DID = did; ndlp->nlp_phba = phba; ndlp->nlp_sid = NLP_NO_SID; kref_init(&ndlp->kref); return; } void lpfc_nlp_release(struct kref *kref) { struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, kref); lpfc_nlp_remove(ndlp->nlp_phba, ndlp); mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool); } struct lpfc_nodelist * lpfc_nlp_get(struct lpfc_nodelist *ndlp) { if (ndlp) kref_get(&ndlp->kref); return ndlp; } int lpfc_nlp_put(struct lpfc_nodelist *ndlp) { return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0; } drivers/scsi/lpfc/lpfc_init.c +7 −8 Original line number Diff line number Diff line Loading @@ -1187,12 +1187,12 @@ lpfc_cleanup(struct lpfc_hba * phba) lpfc_can_disctmo(phba); list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, Loading @@ -1202,27 +1202,27 @@ lpfc_cleanup(struct lpfc_hba * phba) list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } INIT_LIST_HEAD(&phba->fc_nlpmap_list); Loading Loading @@ -1510,7 +1510,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) INIT_LIST_HEAD(&phba->fc_prli_list); INIT_LIST_HEAD(&phba->fc_npr_list); pci_set_master(pdev); retval = pci_set_mwi(pdev); if (retval) Loading Loading
drivers/scsi/lpfc/lpfc_crtn.h +2 −1 Original line number Diff line number Diff line Loading @@ -51,8 +51,9 @@ int lpfc_can_disctmo(struct lpfc_hba *); int lpfc_unreg_rpi(struct lpfc_hba *, struct lpfc_nodelist *); int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *, struct lpfc_nodelist *); int lpfc_nlp_remove(struct lpfc_hba *, struct lpfc_nodelist *); void lpfc_nlp_init(struct lpfc_hba *, struct lpfc_nodelist *, uint32_t); struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); int lpfc_nlp_put(struct lpfc_nodelist *); struct lpfc_nodelist *lpfc_setup_disc_node(struct lpfc_hba *, uint32_t); void lpfc_disc_list_loopmap(struct lpfc_hba *); void lpfc_disc_start(struct lpfc_hba *); Loading
drivers/scsi/lpfc/lpfc_disc.h +1 −2 Original line number Diff line number Diff line Loading @@ -69,7 +69,6 @@ struct lpfc_nodelist { uint16_t nlp_maxframe; /* Max RCV frame size */ uint8_t nlp_class_sup; /* Supported Classes */ uint8_t nlp_retry; /* used for ELS retries */ uint8_t nlp_disc_refcnt; /* used for DSM */ uint8_t nlp_fcp_info; /* class info, bits 0-3 */ #define NLP_FCP_2_DEVICE 0x10 /* FCP-2 device */ Loading @@ -80,6 +79,7 @@ struct lpfc_nodelist { struct lpfc_work_evt els_retry_evt; unsigned long last_ramp_up_time; /* jiffy of last ramp up */ unsigned long last_q_full_time; /* jiffy of last queue full */ struct kref kref; }; /* Defines for nlp_flag (uint32) */ Loading Loading @@ -107,7 +107,6 @@ struct lpfc_nodelist { ACC */ #define NLP_NPR_ADISC 0x2000000 /* Issue ADISC when dq'ed from NPR list */ #define NLP_DELAY_REMOVE 0x4000000 /* Defer removal till end of DSM */ #define NLP_NODEV_REMOVE 0x8000000 /* Defer removal till discovery ends */ /* Defines for list searchs */ Loading
drivers/scsi/lpfc/lpfc_els.c +59 −48 Original line number Diff line number Diff line Loading @@ -209,9 +209,9 @@ lpfc_prep_els_iocb(struct lpfc_hba * phba, uint8_t expectRsp, } /* Save for completion so we can release these resources */ elsiocb->context1 = (uint8_t *) ndlp; elsiocb->context2 = (uint8_t *) pcmd; elsiocb->context3 = (uint8_t *) pbuflist; elsiocb->context1 = lpfc_nlp_get(ndlp); elsiocb->context2 = pcmd; elsiocb->context3 = pbuflist; elsiocb->retry = retry; elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT; Loading Loading @@ -305,7 +305,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, goto fail_free_mbox; mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login; mbox->context2 = ndlp; mbox->context2 = lpfc_nlp_get(ndlp); rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT | MBX_STOP_IOCB); if (rc == MBX_NOT_FINISHED) Loading @@ -314,6 +314,7 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, return 0; fail_issue_reg_login: lpfc_nlp_put(ndlp); mp = (struct lpfc_dmabuf *) mbox->context1; lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading Loading @@ -369,7 +370,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, mempool_free(mbox, phba->mbox_mem_pool); goto fail; } mempool_free(ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, PT2PT_RemoteID); if (!ndlp) { Loading @@ -392,7 +393,7 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, ndlp->nlp_flag |= NLP_NPR_2B_DISC; } else { /* This side will wait for the PLOGI */ mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); } spin_lock_irq(phba->host->host_lock); Loading @@ -407,8 +408,8 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, } static void lpfc_cmpl_els_flogi(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, struct lpfc_iocbq * rspiocb) lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_iocbq *rspiocb) { IOCB_t *irsp = &rspiocb->iocb; struct lpfc_nodelist *ndlp = cmdiocb->context1; Loading @@ -418,7 +419,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, /* Check to see if link went down during discovery */ if (lpfc_els_chk_latt(phba)) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); goto out; } Loading @@ -433,13 +434,12 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, phba->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); spin_unlock_irq(phba->host->host_lock); /* If private loop, then allow max outstandting els to be /* If private loop, then allow max outstanding els to be * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no * alpa map would take too long otherwise. */ if (phba->alpa_map[0] == 0) { phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; phba->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; } /* FLOGI failure */ Loading Loading @@ -484,7 +484,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba * phba, } flogifail: lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && Loading Loading @@ -608,7 +608,7 @@ lpfc_initial_flogi(struct lpfc_hba * phba) lpfc_dequeue_node(phba, ndlp); } if (lpfc_issue_els_flogi(phba, ndlp, 0)) { mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); } return 1; } Loading Loading @@ -1334,7 +1334,7 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_SCR); if (!elsiocb) { mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 1; } Loading @@ -1353,12 +1353,12 @@ lpfc_issue_els_scr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_lock_irq(phba->host->host_lock); if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); return 1; } spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -1387,7 +1387,7 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) elsiocb = lpfc_prep_els_iocb(phba, 1, cmdsize, retry, ndlp, ndlp->nlp_DID, ELS_CMD_RNID); if (!elsiocb) { mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 1; } Loading Loading @@ -1420,12 +1420,12 @@ lpfc_issue_els_farpr(struct lpfc_hba * phba, uint32_t nportid, uint8_t retry) spin_lock_irq(phba->host->host_lock); if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); lpfc_els_free_iocb(phba, elsiocb); return 1; } spin_unlock_irq(phba->host->host_lock); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); return 0; } Loading Loading @@ -1772,6 +1772,10 @@ lpfc_els_free_iocb(struct lpfc_hba * phba, struct lpfc_iocbq * elsiocb) { struct lpfc_dmabuf *buf_ptr, *buf_ptr1; if (elsiocb->context1) { lpfc_nlp_put(elsiocb->context1); elsiocb->context1 = NULL; } /* context2 = cmd, context2->next = rsp, context3 = bpl */ if (elsiocb->context2) { buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2; Loading Loading @@ -1844,7 +1848,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, /* Check to see if link went down during discovery */ if ((lpfc_els_chk_latt(phba)) || !ndlp) { if (lpfc_els_chk_latt(phba) || !ndlp) { if (mbox) { mp = (struct lpfc_dmabuf *) mbox->context1; if (mp) { Loading @@ -1871,7 +1875,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { lpfc_unreg_rpi(phba, ndlp); mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; mbox->context2 = ndlp; mbox->context2 = lpfc_nlp_get(ndlp); ndlp->nlp_prev_state = ndlp->nlp_state; lpfc_nlp_set_state(phba, ndlp, NLP_STE_REG_LOGIN_ISSUE); if (lpfc_sli_issue_mbox(phba, mbox, Loading @@ -1879,6 +1883,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, != MBX_NOT_FINISHED) { goto out; } lpfc_nlp_put(ndlp); /* NOTE: we should have messages for unsuccessful reglogin */ } else { Loading Loading @@ -1983,8 +1988,10 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, return 1; } if (newnode) if (newnode) { lpfc_nlp_put(ndlp); elsiocb->context1 = NULL; } /* Xmit ELS ACC response tag <ulpIoTag> */ lpfc_printf_log(phba, KERN_INFO, LOG_ELS, Loading Loading @@ -2201,8 +2208,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_hba *phba, struct lpfc_iocbq *oldiocb, } static int lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, uint8_t format, lpfc_els_rsp_rnid_acc(struct lpfc_hba *phba, uint8_t format, struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) { RNID *rn; Loading Loading @@ -2270,6 +2276,7 @@ lpfc_els_rsp_rnid_acc(struct lpfc_hba * phba, phba->fc_stat.elsXmitACC++; elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; lpfc_nlp_put(ndlp); elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, * it could be freed */ Loading Loading @@ -2814,6 +2821,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mempool_free(pmb, phba->mbox_mem_pool); elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, lpfc_max_els_tries, ndlp, ndlp->nlp_DID, ELS_CMD_ACC); lpfc_nlp_put(ndlp); if (!elsiocb) return; Loading Loading @@ -2890,13 +2898,14 @@ lpfc_els_rcv_rps(struct lpfc_hba * phba, struct lpfc_iocbq * cmdiocb, lpfc_read_lnk_stat(phba, mbox); mbox->context1 = (void *)((unsigned long)cmdiocb->iocb.ulpContext); mbox->context2 = ndlp; mbox->context2 = lpfc_nlp_get(ndlp); mbox->mbox_cmpl = lpfc_els_rsp_rps_acc; if (lpfc_sli_issue_mbox (phba, mbox, (MBX_NOWAIT | MBX_STOP_IOCB)) != MBX_NOT_FINISHED) { /* Mbox completion will send ELS Response */ return 0; } lpfc_nlp_put(ndlp); mempool_free(mbox, phba->mbox_mem_pool); } } Loading Loading @@ -3284,11 +3293,10 @@ void lpfc_els_flush_cmd(struct lpfc_hba *phba) { LIST_HEAD(completions); struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; struct lpfc_iocbq *tmp_iocb, *piocb; IOCB_t *cmd = NULL; pring = &phba->sli.ring[LPFC_ELS_RING]; spin_lock_irq(phba->host->host_lock); list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) { cmd = &piocb->iocb; Loading @@ -3298,12 +3306,11 @@ lpfc_els_flush_cmd(struct lpfc_hba * phba) } /* Do not flush out the QUE_RING and ABORT/CLOSE iocbs */ if ((cmd->ulpCommand == CMD_QUE_RING_BUF_CN) || (cmd->ulpCommand == CMD_QUE_RING_BUF64_CN) || (cmd->ulpCommand == CMD_CLOSE_XRI_CN) || (cmd->ulpCommand == CMD_ABORT_XRI_CN)) { if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN || cmd->ulpCommand == CMD_QUE_RING_BUF64_CN || cmd->ulpCommand == CMD_CLOSE_XRI_CN || cmd->ulpCommand == CMD_ABORT_XRI_CN) continue; } list_move_tail(&piocb->list, &completions); pring->txq_cnt--; Loading Loading @@ -3422,7 +3429,9 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, } phba->fc_stat.elsRcvFrame++; elsiocb->context1 = ndlp; if (elsiocb->context1) lpfc_nlp_put(elsiocb->context1); elsiocb->context1 = lpfc_nlp_get(ndlp); elsiocb->context2 = mp; if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) { Loading Loading @@ -3553,6 +3562,8 @@ lpfc_els_unsol_event(struct lpfc_hba * phba, lpfc_els_rsp_reject(phba, stat.un.lsRjtError, elsiocb, ndlp); } lpfc_nlp_put(elsiocb->context1); elsiocb->context1 = NULL; if (elsiocb->context2) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); Loading
drivers/scsi/lpfc/lpfc_hbadisc.c +72 −35 Original line number Diff line number Diff line Loading @@ -158,6 +158,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) else { rdata->pnode = NULL; ndlp->rport = NULL; lpfc_nlp_put(ndlp); put_device(&rport->dev); } return; Loading Loading @@ -960,6 +962,7 @@ lpfc_mbx_cmpl_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free( pmb, phba->mbox_mem_pool); lpfc_nlp_put(ndlp); return; } Loading @@ -986,11 +989,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) ndlp = (struct lpfc_nodelist *) pmb->context2; mp = (struct lpfc_dmabuf *) (pmb->context1); pmb->context1 = NULL; pmb->context2 = NULL; if (mb->mbxStatus) { lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); mempool_free( ndlp, phba->nlp_mem_pool); lpfc_nlp_put(ndlp); /* FLOGI failed, so just use loop map to make discovery list */ lpfc_disc_list_loopmap(phba); Loading @@ -1000,12 +1006,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) return; } pmb->context1 = NULL; ndlp->nlp_rpi = mb->un.varWords[0]; ndlp->nlp_type |= NLP_FABRIC; lpfc_nlp_set_state(phba, ndlp, NLP_STE_UNMAPPED_NODE); lpfc_nlp_put(ndlp); /* Drop the reference from the mbox */ if (phba->hba_state == LPFC_FABRIC_CFG_LINK) { /* This NPort has been assigned an NPort_ID by the fabric as a * result of the completed fabric login. Issue a State Change Loading Loading @@ -1075,6 +1081,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mp = (struct lpfc_dmabuf *) (pmb->context1); if (mb->mbxStatus) { lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); Loading Loading @@ -1110,6 +1117,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) lpfc_disc_start(phba); } lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free( pmb, phba->mbox_mem_pool); Loading @@ -1118,8 +1126,7 @@ lpfc_mbx_cmpl_ns_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) } static void lpfc_register_remote_port(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_register_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct fc_rport *rport; struct lpfc_rport_data *rdata; Loading @@ -1131,8 +1138,19 @@ lpfc_register_remote_port(struct lpfc_hba * phba, rport_ids.port_id = ndlp->nlp_DID; rport_ids.roles = FC_RPORT_ROLE_UNKNOWN; /* * We leave our node pointer in rport->dd_data when we unregister a * FCP target port. But fc_remote_port_add zeros the space to which * rport->dd_data points. So, if we're reusing a previously * registered port, drop the reference that we took the last time we * registered the port. */ if (ndlp->rport && ndlp->rport->dd_data && *(struct lpfc_rport_data **) ndlp->rport->dd_data) { lpfc_nlp_put(ndlp); } ndlp->rport = rport = fc_remote_port_add(phba->host, 0, &rport_ids); if (!rport) { if (!rport || !get_device(&rport->dev)) { dev_printk(KERN_WARNING, &phba->pcidev->dev, "Warning: fc_remote_port_add failed\n"); return; Loading @@ -1142,7 +1160,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, rport->maxframe_size = ndlp->nlp_maxframe; rport->supported_classes = ndlp->nlp_class_sup; rdata = rport->dd_data; rdata->pnode = ndlp; rdata->pnode = lpfc_nlp_get(ndlp); if (ndlp->nlp_type & NLP_FCP_TARGET) rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET; Loading @@ -1162,8 +1180,7 @@ lpfc_register_remote_port(struct lpfc_hba * phba, } static void lpfc_unregister_remote_port(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_unregister_remote_port(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct fc_rport *rport = ndlp->rport; struct lpfc_rport_data *rdata = rport->dd_data; Loading @@ -1171,6 +1188,8 @@ lpfc_unregister_remote_port(struct lpfc_hba * phba, if (rport->scsi_target_id == -1) { ndlp->rport = NULL; rdata->pnode = NULL; lpfc_nlp_put(ndlp); put_device(&rport->dev); } fc_remote_port_delete(rport); Loading Loading @@ -1416,7 +1435,7 @@ lpfc_drop_node(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) lpfc_nlp_counters(phba, ndlp->nlp_state, -1); lpfc_delink_node(phba, ndlp); spin_unlock_irq(phba->host->host_lock); lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } /* Loading Loading @@ -1654,6 +1673,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) } list_del(&mb->list); mempool_free(mb, phba->mbox_mem_pool); lpfc_nlp_put(ndlp); } } spin_unlock_irq(phba->host->host_lock); Loading @@ -1679,7 +1699,7 @@ lpfc_freenode(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) * If we are in the middle of using the nlp in the discovery state * machine, defer the free till we reach the end of the state machine. */ int static void lpfc_nlp_remove(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) { struct lpfc_rport_data *rdata; Loading @@ -1688,22 +1708,14 @@ lpfc_nlp_remove(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp) lpfc_cancel_retry_delay_tmo(phba, ndlp); } if (ndlp->nlp_disc_refcnt) { spin_lock_irq(phba->host->host_lock); ndlp->nlp_flag |= NLP_DELAY_REMOVE; spin_unlock_irq(phba->host->host_lock); } else { lpfc_freenode(phba, ndlp); if ((ndlp->rport) && !(phba->fc_flag & FC_UNLOADING)) { put_device(&ndlp->rport->dev); rdata = ndlp->rport->dd_data; rdata->pnode = NULL; ndlp->rport = NULL; } mempool_free( ndlp, phba->nlp_mem_pool); } return 0; } static int Loading Loading @@ -2069,14 +2081,14 @@ lpfc_disc_flush_list(struct lpfc_hba * phba) list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, nlp_listp) { lpfc_free_tx(phba, ndlp); lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } } if (phba->fc_adisc_cnt) { list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, nlp_listp) { lpfc_free_tx(phba, ndlp); lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } } return; Loading Loading @@ -2195,7 +2207,7 @@ lpfc_disc_timeout_handler(struct lpfc_hba *phba) /* Next look for NameServer ndlp */ ndlp = lpfc_findnode_did(phba, NLP_SEARCH_ALL, NameServer_DID); if (ndlp) lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); /* Start discovery */ lpfc_disc_start(phba); break; Loading Loading @@ -2373,6 +2385,8 @@ lpfc_mbx_cmpl_fdmi_reg_login(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb) mod_timer(&phba->fc_fdmitmo, jiffies + HZ * 60); } /* Mailbox took a reference to the node */ lpfc_nlp_put(ndlp); lpfc_mbuf_free(phba, mp->virt, mp->phys); kfree(mp); mempool_free(pmb, phba->mbox_mem_pool); Loading Loading @@ -2460,8 +2474,7 @@ lpfc_findnode_wwpn(struct lpfc_hba * phba, uint32_t order, } void lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, uint32_t did) lpfc_nlp_init(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp, uint32_t did) { memset(ndlp, 0, sizeof (struct lpfc_nodelist)); INIT_LIST_HEAD(&ndlp->els_retry_evt.evt_listp); Loading @@ -2471,5 +2484,29 @@ lpfc_nlp_init(struct lpfc_hba * phba, struct lpfc_nodelist * ndlp, ndlp->nlp_DID = did; ndlp->nlp_phba = phba; ndlp->nlp_sid = NLP_NO_SID; kref_init(&ndlp->kref); return; } void lpfc_nlp_release(struct kref *kref) { struct lpfc_nodelist *ndlp = container_of(kref, struct lpfc_nodelist, kref); lpfc_nlp_remove(ndlp->nlp_phba, ndlp); mempool_free(ndlp, ndlp->nlp_phba->nlp_mem_pool); } struct lpfc_nodelist * lpfc_nlp_get(struct lpfc_nodelist *ndlp) { if (ndlp) kref_get(&ndlp->kref); return ndlp; } int lpfc_nlp_put(struct lpfc_nodelist *ndlp) { return ndlp ? kref_put(&ndlp->kref, lpfc_nlp_release) : 0; }
drivers/scsi/lpfc/lpfc_init.c +7 −8 Original line number Diff line number Diff line Loading @@ -1187,12 +1187,12 @@ lpfc_cleanup(struct lpfc_hba * phba) lpfc_can_disctmo(phba); list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpunmap_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_nlpmap_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_unused_list, Loading @@ -1202,27 +1202,27 @@ lpfc_cleanup(struct lpfc_hba * phba) list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_plogi_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_adisc_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_reglogin_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_prli_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } list_for_each_entry_safe(ndlp, next_ndlp, &phba->fc_npr_list, nlp_listp) { lpfc_nlp_remove(phba, ndlp); lpfc_nlp_put(ndlp); } INIT_LIST_HEAD(&phba->fc_nlpmap_list); Loading Loading @@ -1510,7 +1510,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid) INIT_LIST_HEAD(&phba->fc_prli_list); INIT_LIST_HEAD(&phba->fc_npr_list); pci_set_master(pdev); retval = pci_set_mwi(pdev); if (retval) Loading