summaryrefslogtreecommitdiff
path: root/drivers/scsi/lpfc/lpfc_vport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_vport.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_vport.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c
index 4439167a5188..2797aa75a689 100644
--- a/drivers/scsi/lpfc/lpfc_vport.c
+++ b/drivers/scsi/lpfc/lpfc_vport.c
@@ -246,7 +246,7 @@ static void lpfc_discovery_wait(struct lpfc_vport *vport)
* fabric RA_TOV value and dev_loss tmo. The driver's
* devloss_tmo is 10 giving this loop a 3x multiplier minimally.
*/
- wait_time_max = msecs_to_jiffies(((phba->fc_ratov * 3) + 3) * 1000);
+ wait_time_max = secs_to_jiffies((phba->fc_ratov * 3) + 3);
wait_time_max += jiffies;
start_time = jiffies;
while (time_before(jiffies, wait_time_max)) {
@@ -492,21 +492,22 @@ lpfc_send_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
spin_lock_irq(&ndlp->lock);
- if (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO) &&
+ if (!test_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags) &&
!ndlp->logo_waitq) {
ndlp->logo_waitq = &waitq;
ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
- ndlp->nlp_flag |= NLP_ISSUE_LOGO;
- ndlp->save_flags |= NLP_WAIT_FOR_LOGO;
+ set_bit(NLP_ISSUE_LOGO, &ndlp->nlp_flag);
+ set_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags);
}
spin_unlock_irq(&ndlp->lock);
rc = lpfc_issue_els_npiv_logo(vport, ndlp);
if (!rc) {
wait_event_timeout(waitq,
- (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO)),
- msecs_to_jiffies(phba->fc_ratov * 2000));
+ !test_bit(NLP_WAIT_FOR_LOGO,
+ &ndlp->save_flags),
+ secs_to_jiffies(phba->fc_ratov * 2));
- if (!(ndlp->save_flags & NLP_WAIT_FOR_LOGO))
+ if (!test_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags))
goto logo_cmpl;
/* LOGO wait failed. Correct status. */
rc = -EINTR;
@@ -515,10 +516,8 @@ lpfc_send_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
}
/* Error - clean up node flags. */
- spin_lock_irq(&ndlp->lock);
- ndlp->nlp_flag &= ~NLP_ISSUE_LOGO;
- ndlp->save_flags &= ~NLP_WAIT_FOR_LOGO;
- spin_unlock_irq(&ndlp->lock);
+ clear_bit(NLP_ISSUE_LOGO, &ndlp->nlp_flag);
+ clear_bit(NLP_WAIT_FOR_LOGO, &ndlp->save_flags);
logo_cmpl:
lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT,
@@ -626,6 +625,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
struct lpfc_hba *phba = vport->phba;
int rc;
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
if (vport->port_type == LPFC_PHYSICAL_PORT) {
lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
@@ -679,21 +679,50 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
if (!ndlp)
goto skip_logo;
+ /* Send the DA_ID and Fabric LOGO to cleanup the NPIV fabric entries. */
if (ndlp && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
phba->link_state >= LPFC_LINK_UP &&
phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
if (vport->cfg_enable_da_id) {
- /* Send DA_ID and wait for a completion. */
+ /* Send DA_ID and wait for a completion. This is best
+ * effort. If the DA_ID fails, likely the fabric will
+ * "leak" NportIDs but at least the driver issued the
+ * command.
+ */
+ ndlp = lpfc_findnode_did(vport, NameServer_DID);
+ if (!ndlp)
+ goto issue_logo;
+
+ spin_lock_irq(&ndlp->lock);
+ ndlp->da_id_waitq = &waitq;
+ spin_unlock_irq(&ndlp->lock);
+ set_bit(NLP_WAIT_FOR_DA_ID, &ndlp->save_flags);
+
rc = lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0);
- if (rc) {
- lpfc_printf_log(vport->phba, KERN_WARNING,
- LOG_VPORT,
- "1829 CT command failed to "
- "delete objects on fabric, "
- "rc %d\n", rc);
+ if (!rc) {
+ wait_event_timeout(waitq,
+ !test_bit(NLP_WAIT_FOR_DA_ID,
+ &ndlp->save_flags),
+ secs_to_jiffies(phba->fc_ratov * 2));
}
+
+ lpfc_printf_vlog(vport, KERN_INFO, LOG_VPORT | LOG_ELS,
+ "1829 DA_ID issue status %d. "
+ "SFlag x%lx NState x%x, NFlag x%lx "
+ "Rpi x%x\n",
+ rc, ndlp->save_flags, ndlp->nlp_state,
+ ndlp->nlp_flag, ndlp->nlp_rpi);
+
+ /* Remove the waitq and save_flags. It no
+ * longer matters if the wake happened.
+ */
+ spin_lock_irq(&ndlp->lock);
+ ndlp->da_id_waitq = NULL;
+ spin_unlock_irq(&ndlp->lock);
+ clear_bit(NLP_WAIT_FOR_DA_ID, &ndlp->save_flags);
}
+issue_logo:
/*
* If the vpi is not registered, then a valid FDISC doesn't
* exist and there is no need for a ELS LOGO. Just cleanup