diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_hbadisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 67 |
1 files changed, 65 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f64ce88e8a06..371f41e886d6 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c | |||
@@ -108,6 +108,8 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
108 | struct lpfc_vport *vport; | 108 | struct lpfc_vport *vport; |
109 | struct lpfc_hba *phba; | 109 | struct lpfc_hba *phba; |
110 | struct lpfc_work_evt *evtp; | 110 | struct lpfc_work_evt *evtp; |
111 | int put_node; | ||
112 | int put_rport; | ||
111 | 113 | ||
112 | rdata = rport->dd_data; | 114 | rdata = rport->dd_data; |
113 | ndlp = rdata->pnode; | 115 | ndlp = rdata->pnode; |
@@ -128,6 +130,25 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport) | |||
128 | "rport devlosscb: sid:x%x did:x%x flg:x%x", | 130 | "rport devlosscb: sid:x%x did:x%x flg:x%x", |
129 | ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); | 131 | ndlp->nlp_sid, ndlp->nlp_DID, ndlp->nlp_flag); |
130 | 132 | ||
133 | /* Don't defer this if we are in the process of deleting the vport | ||
134 | * or unloading the driver. The unload will cleanup the node | ||
135 | * appropriately we just need to cleanup the ndlp rport info here. | ||
136 | */ | ||
137 | if (vport->load_flag & FC_UNLOADING) { | ||
138 | put_node = rdata->pnode != NULL; | ||
139 | put_rport = ndlp->rport != NULL; | ||
140 | rdata->pnode = NULL; | ||
141 | ndlp->rport = NULL; | ||
142 | if (put_node) | ||
143 | lpfc_nlp_put(ndlp); | ||
144 | if (put_rport) | ||
145 | put_device(&rport->dev); | ||
146 | return; | ||
147 | } | ||
148 | |||
149 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) | ||
150 | return; | ||
151 | |||
131 | evtp = &ndlp->dev_loss_evt; | 152 | evtp = &ndlp->dev_loss_evt; |
132 | 153 | ||
133 | if (!list_empty(&evtp->evt_listp)) | 154 | if (!list_empty(&evtp->evt_listp)) |
@@ -175,8 +196,23 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp) | |||
175 | "rport devlosstmo:did:x%x type:x%x id:x%x", | 196 | "rport devlosstmo:did:x%x type:x%x id:x%x", |
176 | ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); | 197 | ndlp->nlp_DID, ndlp->nlp_type, rport->scsi_target_id); |
177 | 198 | ||
178 | if (!(vport->load_flag & FC_UNLOADING) && | 199 | /* Don't defer this if we are in the process of deleting the vport |
179 | ndlp->nlp_state == NLP_STE_MAPPED_NODE) | 200 | * or unloading the driver. The unload will cleanup the node |
201 | * appropriately we just need to cleanup the ndlp rport info here. | ||
202 | */ | ||
203 | if (vport->load_flag & FC_UNLOADING) { | ||
204 | put_node = rdata->pnode != NULL; | ||
205 | put_rport = ndlp->rport != NULL; | ||
206 | rdata->pnode = NULL; | ||
207 | ndlp->rport = NULL; | ||
208 | if (put_node) | ||
209 | lpfc_nlp_put(ndlp); | ||
210 | if (put_rport) | ||
211 | put_device(&rport->dev); | ||
212 | return; | ||
213 | } | ||
214 | |||
215 | if (ndlp->nlp_state == NLP_STE_MAPPED_NODE) | ||
180 | return; | 216 | return; |
181 | 217 | ||
182 | if (ndlp->nlp_type & NLP_FABRIC) { | 218 | if (ndlp->nlp_type & NLP_FABRIC) { |
@@ -1965,12 +2001,39 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
1965 | static void | 2001 | static void |
1966 | lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | 2002 | lpfc_nlp_remove(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) |
1967 | { | 2003 | { |
2004 | struct lpfc_hba *phba = vport->phba; | ||
1968 | struct lpfc_rport_data *rdata; | 2005 | struct lpfc_rport_data *rdata; |
2006 | LPFC_MBOXQ_t *mbox; | ||
2007 | int rc; | ||
1969 | 2008 | ||
1970 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { | 2009 | if (ndlp->nlp_flag & NLP_DELAY_TMO) { |
1971 | lpfc_cancel_retry_delay_tmo(vport, ndlp); | 2010 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
1972 | } | 2011 | } |
1973 | 2012 | ||
2013 | if (ndlp->nlp_flag & NLP_DEFER_RM && !ndlp->nlp_rpi) { | ||
2014 | /* For this case we need to cleanup the default rpi | ||
2015 | * allocated by the firmware. | ||
2016 | */ | ||
2017 | if ((mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL)) | ||
2018 | != NULL) { | ||
2019 | rc = lpfc_reg_login(phba, vport->vpi, ndlp->nlp_DID, | ||
2020 | (uint8_t *) &vport->fc_sparam, mbox, 0); | ||
2021 | if (rc) { | ||
2022 | mempool_free(mbox, phba->mbox_mem_pool); | ||
2023 | } | ||
2024 | else { | ||
2025 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; | ||
2026 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | ||
2027 | mbox->vport = vport; | ||
2028 | mbox->context2 = 0; | ||
2029 | rc =lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); | ||
2030 | if (rc == MBX_NOT_FINISHED) { | ||
2031 | mempool_free(mbox, phba->mbox_mem_pool); | ||
2032 | } | ||
2033 | } | ||
2034 | } | ||
2035 | } | ||
2036 | |||
1974 | lpfc_cleanup_node(vport, ndlp); | 2037 | lpfc_cleanup_node(vport, ndlp); |
1975 | 2038 | ||
1976 | /* | 2039 | /* |