|
47 | 47 | #include "lpfc_debugfs.h" |
48 | 48 |
|
49 | 49 |
|
| 50 | +/* Called to clear RSCN discovery flags when driver is unloading. */ |
| 51 | +static bool |
| 52 | +lpfc_check_unload_and_clr_rscn(unsigned long *fc_flag) |
| 53 | +{ |
| 54 | + /* If unloading, then clear the FC_RSCN_DEFERRED flag */ |
| 55 | + if (test_bit(FC_UNLOADING, fc_flag)) { |
| 56 | + clear_bit(FC_RSCN_DEFERRED, fc_flag); |
| 57 | + return false; |
| 58 | + } |
| 59 | + return test_bit(FC_RSCN_DEFERRED, fc_flag); |
| 60 | +} |
| 61 | + |
50 | 62 | /* Called to verify a rcv'ed ADISC was intended for us. */ |
51 | 63 | static int |
52 | 64 | lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
@@ -213,8 +225,10 @@ void |
213 | 225 | lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
214 | 226 | { |
215 | 227 | LIST_HEAD(abort_list); |
| 228 | + LIST_HEAD(drv_cmpl_list); |
216 | 229 | struct lpfc_sli_ring *pring; |
217 | 230 | struct lpfc_iocbq *iocb, *next_iocb; |
| 231 | + int retval = 0; |
218 | 232 |
|
219 | 233 | pring = lpfc_phba_elsring(phba); |
220 | 234 |
|
@@ -250,11 +264,20 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) |
250 | 264 |
|
251 | 265 | /* Abort the targeted IOs and remove them from the abort list. */ |
252 | 266 | list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) { |
253 | | - spin_lock_irq(&phba->hbalock); |
254 | | - list_del_init(&iocb->dlist); |
255 | | - lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL); |
256 | | - spin_unlock_irq(&phba->hbalock); |
| 267 | + spin_lock_irq(&phba->hbalock); |
| 268 | + list_del_init(&iocb->dlist); |
| 269 | + retval = lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL); |
| 270 | + spin_unlock_irq(&phba->hbalock); |
| 271 | + |
| 272 | + if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) { |
| 273 | + list_del_init(&iocb->list); |
| 274 | + list_add_tail(&iocb->list, &drv_cmpl_list); |
| 275 | + } |
257 | 276 | } |
| 277 | + |
| 278 | + lpfc_sli_cancel_iocbs(phba, &drv_cmpl_list, IOSTAT_LOCAL_REJECT, |
| 279 | + IOERR_SLI_ABORTED); |
| 280 | + |
258 | 281 | /* Make sure HBA is alive */ |
259 | 282 | lpfc_issue_hb_tmo(phba); |
260 | 283 |
|
@@ -1604,10 +1627,8 @@ lpfc_device_recov_plogi_issue(struct lpfc_vport *vport, |
1604 | 1627 | { |
1605 | 1628 | struct lpfc_hba *phba = vport->phba; |
1606 | 1629 |
|
1607 | | - /* Don't do anything that will mess up processing of the |
1608 | | - * previous RSCN. |
1609 | | - */ |
1610 | | - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) |
| 1630 | + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ |
| 1631 | + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) |
1611 | 1632 | return ndlp->nlp_state; |
1612 | 1633 |
|
1613 | 1634 | /* software abort outstanding PLOGI */ |
@@ -1790,10 +1811,8 @@ lpfc_device_recov_adisc_issue(struct lpfc_vport *vport, |
1790 | 1811 | { |
1791 | 1812 | struct lpfc_hba *phba = vport->phba; |
1792 | 1813 |
|
1793 | | - /* Don't do anything that will mess up processing of the |
1794 | | - * previous RSCN. |
1795 | | - */ |
1796 | | - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) |
| 1814 | + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ |
| 1815 | + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) |
1797 | 1816 | return ndlp->nlp_state; |
1798 | 1817 |
|
1799 | 1818 | /* software abort outstanding ADISC */ |
@@ -2059,10 +2078,8 @@ lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport, |
2059 | 2078 | void *arg, |
2060 | 2079 | uint32_t evt) |
2061 | 2080 | { |
2062 | | - /* Don't do anything that will mess up processing of the |
2063 | | - * previous RSCN. |
2064 | | - */ |
2065 | | - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) |
| 2081 | + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ |
| 2082 | + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) |
2066 | 2083 | return ndlp->nlp_state; |
2067 | 2084 |
|
2068 | 2085 | ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; |
@@ -2375,10 +2392,8 @@ lpfc_device_recov_prli_issue(struct lpfc_vport *vport, |
2375 | 2392 | { |
2376 | 2393 | struct lpfc_hba *phba = vport->phba; |
2377 | 2394 |
|
2378 | | - /* Don't do anything that will mess up processing of the |
2379 | | - * previous RSCN. |
2380 | | - */ |
2381 | | - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) |
| 2395 | + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ |
| 2396 | + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) |
2382 | 2397 | return ndlp->nlp_state; |
2383 | 2398 |
|
2384 | 2399 | /* software abort outstanding PRLI */ |
@@ -2894,10 +2909,8 @@ static uint32_t |
2894 | 2909 | lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
2895 | 2910 | void *arg, uint32_t evt) |
2896 | 2911 | { |
2897 | | - /* Don't do anything that will mess up processing of the |
2898 | | - * previous RSCN. |
2899 | | - */ |
2900 | | - if (test_bit(FC_RSCN_DEFERRED, &vport->fc_flag)) |
| 2912 | + /* Don't do anything that disrupts the RSCN unless lpfc is unloading. */ |
| 2913 | + if (lpfc_check_unload_and_clr_rscn(&vport->fc_flag)) |
2901 | 2914 | return ndlp->nlp_state; |
2902 | 2915 |
|
2903 | 2916 | lpfc_cancel_retry_delay_tmo(vport, ndlp); |
|
0 commit comments