mirror of
https://github.com/adulau/aha.git
synced 2025-01-04 07:03:38 +00:00
[SCSI] lpfc 8.2.8 : Miscellaneous Discovery Fixes
Miscellaneous Discovery fixes: - Fix rejection followed by acceptance in handling RPL and RPS unsolicited events - Fix for vport delete crash - Fix PLOGI vs ADISC race condition Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
parent
e59058c440
commit
90160e010b
4 changed files with 172 additions and 110 deletions
|
@ -1555,6 +1555,83 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lpfc_rscn_disc: Perform rscn discovery for a vport.
|
||||||
|
* @vport: pointer to a host virtual N_Port data structure.
|
||||||
|
*
|
||||||
|
* This routine performs Registration State Change Notification (RSCN)
|
||||||
|
* discovery for a @vport. If the @vport's node port recovery count is not
|
||||||
|
* zero, it will invoke the lpfc_els_disc_plogi() to perform PLOGI for all
|
||||||
|
* the nodes that need recovery. If none of the PLOGI were needed through
|
||||||
|
* the lpfc_els_disc_plogi() routine, the lpfc_end_rscn() routine shall be
|
||||||
|
* invoked to check and handle possible more RSCN came in during the period
|
||||||
|
* of processing the current ones.
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
lpfc_rscn_disc(struct lpfc_vport *vport)
|
||||||
|
{
|
||||||
|
lpfc_can_disctmo(vport);
|
||||||
|
|
||||||
|
/* RSCN discovery */
|
||||||
|
/* go thru NPR nodes and issue ELS PLOGIs */
|
||||||
|
if (vport->fc_npr_cnt)
|
||||||
|
if (lpfc_els_disc_plogi(vport))
|
||||||
|
return;
|
||||||
|
|
||||||
|
lpfc_end_rscn(vport);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lpfc_adisc_done: Complete the adisc phase of discovery.
|
||||||
|
* @vport: pointer to lpfc_vport hba data structure that finished all ADISCs.
|
||||||
|
*
|
||||||
|
* This function is called when the final ADISC is completed during discovery.
|
||||||
|
* This function handles clearing link attention or issuing reg_vpi depending
|
||||||
|
* on whether npiv is enabled. This function also kicks off the PLOGI phase of
|
||||||
|
* discovery.
|
||||||
|
* This function is called with no locks held.
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
lpfc_adisc_done(struct lpfc_vport *vport)
|
||||||
|
{
|
||||||
|
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||||
|
struct lpfc_hba *phba = vport->phba;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For NPIV, cmpl_reg_vpi will set port_state to READY,
|
||||||
|
* and continue discovery.
|
||||||
|
*/
|
||||||
|
if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
|
||||||
|
!(vport->fc_flag & FC_RSCN_MODE)) {
|
||||||
|
lpfc_issue_reg_vpi(phba, vport);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* For SLI2, we need to set port_state to READY
|
||||||
|
* and continue discovery.
|
||||||
|
*/
|
||||||
|
if (vport->port_state < LPFC_VPORT_READY) {
|
||||||
|
/* If we get here, there is nothing to ADISC */
|
||||||
|
if (vport->port_type == LPFC_PHYSICAL_PORT)
|
||||||
|
lpfc_issue_clear_la(phba, vport);
|
||||||
|
if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
|
||||||
|
vport->num_disc_nodes = 0;
|
||||||
|
/* go thru NPR list, issue ELS PLOGIs */
|
||||||
|
if (vport->fc_npr_cnt)
|
||||||
|
lpfc_els_disc_plogi(vport);
|
||||||
|
if (!vport->num_disc_nodes) {
|
||||||
|
spin_lock_irq(shost->host_lock);
|
||||||
|
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
||||||
|
spin_unlock_irq(shost->host_lock);
|
||||||
|
lpfc_can_disctmo(vport);
|
||||||
|
lpfc_end_rscn(vport);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vport->port_state = LPFC_VPORT_READY;
|
||||||
|
} else
|
||||||
|
lpfc_rscn_disc(vport);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lpfc_more_adisc: Issue more adisc as needed.
|
* lpfc_more_adisc: Issue more adisc as needed.
|
||||||
* @vport: pointer to a host virtual N_Port data structure.
|
* @vport: pointer to a host virtual N_Port data structure.
|
||||||
|
@ -1583,35 +1660,11 @@ lpfc_more_adisc(struct lpfc_vport *vport)
|
||||||
/* go thru NPR nodes and issue any remaining ELS ADISCs */
|
/* go thru NPR nodes and issue any remaining ELS ADISCs */
|
||||||
sentadisc = lpfc_els_disc_adisc(vport);
|
sentadisc = lpfc_els_disc_adisc(vport);
|
||||||
}
|
}
|
||||||
|
if (!vport->num_disc_nodes)
|
||||||
|
lpfc_adisc_done(vport);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* lpfc_rscn_disc: Perform rscn discovery for a vport.
|
|
||||||
* @vport: pointer to a host virtual N_Port data structure.
|
|
||||||
*
|
|
||||||
* This routine performs Registration State Change Notification (RSCN)
|
|
||||||
* discovery for a @vport. If the @vport's node port recovery count is not
|
|
||||||
* zero, it will invoke the lpfc_els_disc_plogi() to perform PLOGI for all
|
|
||||||
* the nodes that need recovery. If none of the PLOGI were needed through
|
|
||||||
* the lpfc_els_disc_plogi() routine, the lpfc_end_rscn() routine shall be
|
|
||||||
* invoked to check and handle possible more RSCN came in during the period
|
|
||||||
* of processing the current ones.
|
|
||||||
**/
|
|
||||||
static void
|
|
||||||
lpfc_rscn_disc(struct lpfc_vport *vport)
|
|
||||||
{
|
|
||||||
lpfc_can_disctmo(vport);
|
|
||||||
|
|
||||||
/* RSCN discovery */
|
|
||||||
/* go thru NPR nodes and issue ELS PLOGIs */
|
|
||||||
if (vport->fc_npr_cnt)
|
|
||||||
if (lpfc_els_disc_plogi(vport))
|
|
||||||
return;
|
|
||||||
|
|
||||||
lpfc_end_rscn(vport);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lpfc_cmpl_els_adisc: Completion callback function for adisc.
|
* lpfc_cmpl_els_adisc: Completion callback function for adisc.
|
||||||
* @phba: pointer to lpfc hba data structure.
|
* @phba: pointer to lpfc hba data structure.
|
||||||
|
@ -1692,52 +1745,9 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
|
||||||
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
|
lpfc_disc_state_machine(vport, ndlp, cmdiocb,
|
||||||
NLP_EVT_CMPL_ADISC);
|
NLP_EVT_CMPL_ADISC);
|
||||||
|
|
||||||
if (disc && vport->num_disc_nodes) {
|
/* Check to see if there are more ADISCs to be sent */
|
||||||
/* Check to see if there are more ADISCs to be sent */
|
if (disc && vport->num_disc_nodes)
|
||||||
lpfc_more_adisc(vport);
|
lpfc_more_adisc(vport);
|
||||||
|
|
||||||
/* Check to see if we are done with ADISC authentication */
|
|
||||||
if (vport->num_disc_nodes == 0) {
|
|
||||||
/* If we get here, there is nothing left to ADISC */
|
|
||||||
/*
|
|
||||||
* For NPIV, cmpl_reg_vpi will set port_state to READY,
|
|
||||||
* and continue discovery.
|
|
||||||
*/
|
|
||||||
if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
|
|
||||||
!(vport->fc_flag & FC_RSCN_MODE)) {
|
|
||||||
lpfc_issue_reg_vpi(phba, vport);
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* For SLI2, we need to set port_state to READY
|
|
||||||
* and continue discovery.
|
|
||||||
*/
|
|
||||||
if (vport->port_state < LPFC_VPORT_READY) {
|
|
||||||
/* If we get here, there is nothing to ADISC */
|
|
||||||
if (vport->port_type == LPFC_PHYSICAL_PORT)
|
|
||||||
lpfc_issue_clear_la(phba, vport);
|
|
||||||
|
|
||||||
if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
|
|
||||||
vport->num_disc_nodes = 0;
|
|
||||||
/* go thru NPR list, issue ELS PLOGIs */
|
|
||||||
if (vport->fc_npr_cnt)
|
|
||||||
lpfc_els_disc_plogi(vport);
|
|
||||||
|
|
||||||
if (!vport->num_disc_nodes) {
|
|
||||||
spin_lock_irq(shost->host_lock);
|
|
||||||
vport->fc_flag &=
|
|
||||||
~FC_NDISC_ACTIVE;
|
|
||||||
spin_unlock_irq(
|
|
||||||
shost->host_lock);
|
|
||||||
lpfc_can_disctmo(vport);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vport->port_state = LPFC_VPORT_READY;
|
|
||||||
} else {
|
|
||||||
lpfc_rscn_disc(vport);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
lpfc_els_free_iocb(phba, cmdiocb);
|
lpfc_els_free_iocb(phba, cmdiocb);
|
||||||
return;
|
return;
|
||||||
|
@ -2258,19 +2268,16 @@ lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
|
||||||
if (vport->port_state < LPFC_VPORT_READY) {
|
if (vport->port_state < LPFC_VPORT_READY) {
|
||||||
/* Check if there are more ADISCs to be sent */
|
/* Check if there are more ADISCs to be sent */
|
||||||
lpfc_more_adisc(vport);
|
lpfc_more_adisc(vport);
|
||||||
if ((vport->num_disc_nodes == 0) &&
|
|
||||||
(vport->fc_npr_cnt))
|
|
||||||
lpfc_els_disc_plogi(vport);
|
|
||||||
} else {
|
} else {
|
||||||
/* Check if there are more PLOGIs to be sent */
|
/* Check if there are more PLOGIs to be sent */
|
||||||
lpfc_more_plogi(vport);
|
lpfc_more_plogi(vport);
|
||||||
}
|
if (vport->num_disc_nodes == 0) {
|
||||||
if (vport->num_disc_nodes == 0) {
|
spin_lock_irq(shost->host_lock);
|
||||||
spin_lock_irq(shost->host_lock);
|
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
||||||
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
spin_unlock_irq(shost->host_lock);
|
||||||
spin_unlock_irq(shost->host_lock);
|
lpfc_can_disctmo(vport);
|
||||||
lpfc_can_disctmo(vport);
|
lpfc_end_rscn(vport);
|
||||||
lpfc_end_rscn(vport);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4480,14 +4487,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||||
struct ls_rjt stat;
|
struct ls_rjt stat;
|
||||||
|
|
||||||
if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
|
if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
|
||||||
(ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
|
(ndlp->nlp_state != NLP_STE_MAPPED_NODE))
|
||||||
stat.un.b.lsRjtRsvd0 = 0;
|
/* reject the unsolicited RPS request and done with it */
|
||||||
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
goto reject_out;
|
||||||
stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
|
|
||||||
stat.un.b.vendorUnique = 0;
|
|
||||||
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
|
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
|
||||||
lp = (uint32_t *) pcmd->virt;
|
lp = (uint32_t *) pcmd->virt;
|
||||||
|
@ -4520,6 +4522,9 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||||
mempool_free(mbox, phba->mbox_mem_pool);
|
mempool_free(mbox, phba->mbox_mem_pool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reject_out:
|
||||||
|
/* issue rejection response */
|
||||||
stat.un.b.lsRjtRsvd0 = 0;
|
stat.un.b.lsRjtRsvd0 = 0;
|
||||||
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
||||||
stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
|
stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
|
||||||
|
@ -4629,12 +4634,15 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
|
||||||
|
|
||||||
if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
|
if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
|
||||||
(ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
|
(ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
|
||||||
|
/* issue rejection response */
|
||||||
stat.un.b.lsRjtRsvd0 = 0;
|
stat.un.b.lsRjtRsvd0 = 0;
|
||||||
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
|
||||||
stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
|
stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
|
||||||
stat.un.b.vendorUnique = 0;
|
stat.un.b.vendorUnique = 0;
|
||||||
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
|
lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
|
||||||
NULL);
|
NULL);
|
||||||
|
/* rejected the unsolicited RPL request and done with it */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
|
pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
|
||||||
|
|
|
@ -1580,14 +1580,6 @@ lpfc_cleanup(struct lpfc_vport *vport)
|
||||||
lpfc_disc_state_machine(vport, ndlp, NULL,
|
lpfc_disc_state_machine(vport, ndlp, NULL,
|
||||||
NLP_EVT_DEVICE_RM);
|
NLP_EVT_DEVICE_RM);
|
||||||
|
|
||||||
/* nlp_type zero is not defined, nlp_flag zero also not defined,
|
|
||||||
* nlp_state is unused, this happens when
|
|
||||||
* an initiator has logged
|
|
||||||
* into us so cleanup this ndlp.
|
|
||||||
*/
|
|
||||||
if ((ndlp->nlp_type == 0) && (ndlp->nlp_flag == 0) &&
|
|
||||||
(ndlp->nlp_state == 0))
|
|
||||||
lpfc_nlp_put(ndlp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At this point, ALL ndlp's should be gone
|
/* At this point, ALL ndlp's should be gone
|
||||||
|
|
|
@ -1003,20 +1003,8 @@ lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||||
spin_lock_irq(shost->host_lock);
|
spin_lock_irq(shost->host_lock);
|
||||||
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
|
if (vport->num_disc_nodes)
|
||||||
if (vport->num_disc_nodes) {
|
|
||||||
lpfc_more_adisc(vport);
|
lpfc_more_adisc(vport);
|
||||||
if ((vport->num_disc_nodes == 0) &&
|
|
||||||
(vport->fc_npr_cnt))
|
|
||||||
lpfc_els_disc_plogi(vport);
|
|
||||||
if (vport->num_disc_nodes == 0) {
|
|
||||||
spin_lock_irq(shost->host_lock);
|
|
||||||
vport->fc_flag &= ~FC_NDISC_ACTIVE;
|
|
||||||
spin_unlock_irq(shost->host_lock);
|
|
||||||
lpfc_can_disctmo(vport);
|
|
||||||
lpfc_end_rscn(vport);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return ndlp->nlp_state;
|
return ndlp->nlp_state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,6 +204,77 @@ lpfc_unique_wwpn(struct lpfc_hba *phba, struct lpfc_vport *new_vport)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lpfc_discovery_wait: Wait for driver discovery to quiesce.
|
||||||
|
* @vport: The virtual port for which this call is being executed.
|
||||||
|
*
|
||||||
|
* This driver calls this routine specifically from lpfc_vport_delete
|
||||||
|
* to enforce a synchronous execution of vport
|
||||||
|
* delete relative to discovery activities. The
|
||||||
|
* lpfc_vport_delete routine should not return until it
|
||||||
|
* can reasonably guarantee that discovery has quiesced.
|
||||||
|
* Post FDISC LOGO, the driver must wait until its SAN teardown is
|
||||||
|
* complete and all resources recovered before allowing
|
||||||
|
* cleanup.
|
||||||
|
*
|
||||||
|
* This routine does not require any locks held.
|
||||||
|
**/
|
||||||
|
static void lpfc_discovery_wait(struct lpfc_vport *vport)
|
||||||
|
{
|
||||||
|
struct lpfc_hba *phba = vport->phba;
|
||||||
|
uint32_t wait_flags = 0;
|
||||||
|
unsigned long wait_time_max;
|
||||||
|
unsigned long start_time;
|
||||||
|
|
||||||
|
wait_flags = FC_RSCN_MODE | FC_RSCN_DISCOVERY | FC_NLP_MORE |
|
||||||
|
FC_RSCN_DEFERRED | FC_NDISC_ACTIVE | FC_DISC_TMO;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The time constraint on this loop is a balance between the
|
||||||
|
* 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 += jiffies;
|
||||||
|
start_time = jiffies;
|
||||||
|
while (time_before(jiffies, wait_time_max)) {
|
||||||
|
if ((vport->num_disc_nodes > 0) ||
|
||||||
|
(vport->fc_flag & wait_flags) ||
|
||||||
|
((vport->port_state > LPFC_VPORT_FAILED) &&
|
||||||
|
(vport->port_state < LPFC_VPORT_READY))) {
|
||||||
|
lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
|
||||||
|
"1833 Vport discovery quiesce Wait:"
|
||||||
|
" vpi x%x state x%x fc_flags x%x"
|
||||||
|
" num_nodes x%x, waiting 1000 msecs"
|
||||||
|
" total wait msecs x%x\n",
|
||||||
|
vport->vpi, vport->port_state,
|
||||||
|
vport->fc_flag, vport->num_disc_nodes,
|
||||||
|
jiffies_to_msecs(jiffies - start_time));
|
||||||
|
msleep(1000);
|
||||||
|
} else {
|
||||||
|
/* Base case. Wait variants satisfied. Break out */
|
||||||
|
lpfc_printf_log(phba, KERN_INFO, LOG_VPORT,
|
||||||
|
"1834 Vport discovery quiesced:"
|
||||||
|
" vpi x%x state x%x fc_flags x%x"
|
||||||
|
" wait msecs x%x\n",
|
||||||
|
vport->vpi, vport->port_state,
|
||||||
|
vport->fc_flag,
|
||||||
|
jiffies_to_msecs(jiffies
|
||||||
|
- start_time));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_after(jiffies, wait_time_max))
|
||||||
|
lpfc_printf_log(phba, KERN_ERR, LOG_VPORT,
|
||||||
|
"1835 Vport discovery quiesce failed:"
|
||||||
|
" vpi x%x state x%x fc_flags x%x"
|
||||||
|
" wait msecs x%x\n",
|
||||||
|
vport->vpi, vport->port_state,
|
||||||
|
vport->fc_flag,
|
||||||
|
jiffies_to_msecs(jiffies - start_time));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
|
lpfc_vport_create(struct fc_vport *fc_vport, bool disable)
|
||||||
{
|
{
|
||||||
|
@ -602,6 +673,9 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
||||||
timeout = schedule_timeout(timeout);
|
timeout = schedule_timeout(timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(phba->pport->load_flag & FC_UNLOADING))
|
||||||
|
lpfc_discovery_wait(vport);
|
||||||
|
|
||||||
skip_logo:
|
skip_logo:
|
||||||
lpfc_cleanup(vport);
|
lpfc_cleanup(vport);
|
||||||
lpfc_sli_host_down(vport);
|
lpfc_sli_host_down(vport);
|
||||||
|
|
Loading…
Reference in a new issue