aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_nportdisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index b90820a699fd..bccc9c66fa37 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -190,6 +190,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
190} 190}
191 191
192 192
193
193/* 194/*
194 * Free resources / clean up outstanding I/Os 195 * Free resources / clean up outstanding I/Os
195 * associated with a LPFC_NODELIST entry. This 196 * associated with a LPFC_NODELIST entry. This
@@ -199,13 +200,15 @@ int
199lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) 200lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
200{ 201{
201 LIST_HEAD(completions); 202 LIST_HEAD(completions);
203 LIST_HEAD(txcmplq_completions);
204 LIST_HEAD(abort_list);
202 struct lpfc_sli *psli = &phba->sli; 205 struct lpfc_sli *psli = &phba->sli;
203 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING]; 206 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
204 struct lpfc_iocbq *iocb, *next_iocb; 207 struct lpfc_iocbq *iocb, *next_iocb;
205 208
206 /* Abort outstanding I/O on NPort <nlp_DID> */ 209 /* Abort outstanding I/O on NPort <nlp_DID> */
207 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY, 210 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY,
208 "0205 Abort outstanding I/O on NPort x%x " 211 "2819 Abort outstanding I/O on NPort x%x "
209 "Data: x%x x%x x%x\n", 212 "Data: x%x x%x x%x\n",
210 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, 213 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
211 ndlp->nlp_rpi); 214 ndlp->nlp_rpi);
@@ -224,14 +227,25 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
224 } 227 }
225 228
226 /* Next check the txcmplq */ 229 /* Next check the txcmplq */
227 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { 230 list_splice_init(&pring->txcmplq, &txcmplq_completions);
231 spin_unlock_irq(&phba->hbalock);
232
233 list_for_each_entry_safe(iocb, next_iocb, &txcmplq_completions, list) {
228 /* Check to see if iocb matches the nport we are looking for */ 234 /* Check to see if iocb matches the nport we are looking for */
229 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) { 235 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))
230 lpfc_sli_issue_abort_iotag(phba, pring, iocb); 236 list_add_tail(&iocb->dlist, &abort_list);
231 }
232 } 237 }
238 spin_lock_irq(&phba->hbalock);
239 list_splice(&txcmplq_completions, &pring->txcmplq);
233 spin_unlock_irq(&phba->hbalock); 240 spin_unlock_irq(&phba->hbalock);
234 241
242 list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) {
243 spin_lock_irq(&phba->hbalock);
244 list_del_init(&iocb->dlist);
245 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
246 spin_unlock_irq(&phba->hbalock);
247 }
248
235 /* Cancel all the IOCBs from the completions list */ 249 /* Cancel all the IOCBs from the completions list */
236 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT, 250 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
237 IOERR_SLI_ABORTED); 251 IOERR_SLI_ABORTED);
@@ -626,7 +640,8 @@ lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
626 if (!(vport->fc_flag & FC_PT2PT)) { 640 if (!(vport->fc_flag & FC_PT2PT)) {
627 /* Check config parameter use-adisc or FCP-2 */ 641 /* Check config parameter use-adisc or FCP-2 */
628 if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) || 642 if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
629 ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) { 643 ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) &&
644 (ndlp->nlp_type & NLP_FCP_TARGET))) {
630 spin_lock_irq(shost->host_lock); 645 spin_lock_irq(shost->host_lock);
631 ndlp->nlp_flag |= NLP_NPR_ADISC; 646 ndlp->nlp_flag |= NLP_NPR_ADISC;
632 spin_unlock_irq(shost->host_lock); 647 spin_unlock_irq(shost->host_lock);
@@ -962,6 +977,7 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
962 mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login; 977 mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login;
963 break; 978 break;
964 default: 979 default:
980 ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
965 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; 981 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
966 } 982 }
967 mbox->context2 = lpfc_nlp_get(ndlp); 983 mbox->context2 = lpfc_nlp_get(ndlp);
@@ -972,6 +988,8 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
972 NLP_STE_REG_LOGIN_ISSUE); 988 NLP_STE_REG_LOGIN_ISSUE);
973 return ndlp->nlp_state; 989 return ndlp->nlp_state;
974 } 990 }
991 if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)
992 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
975 /* decrement node reference count to the failed mbox 993 /* decrement node reference count to the failed mbox
976 * command 994 * command
977 */ 995 */
@@ -1458,6 +1476,7 @@ lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
1458 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE; 1476 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1459 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 1477 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1460 spin_lock_irq(shost->host_lock); 1478 spin_lock_irq(shost->host_lock);
1479 ndlp->nlp_flag |= NLP_IGNR_REG_CMPL;
1461 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC); 1480 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1462 spin_unlock_irq(shost->host_lock); 1481 spin_unlock_irq(shost->host_lock);
1463 lpfc_disc_set_adisc(vport, ndlp); 1482 lpfc_disc_set_adisc(vport, ndlp);