[SCSI] lpfc 8.3.7: Fix discovery failures.

Fix discovery failures:
- Move all accesses to the fc_flag field inside the host lock.
- Restore link state after going through linkdown processing for FCF DEAD event.

Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
James Smart 2009-12-21 17:03:15 -05:00 committed by James Bottomley
parent aacc20e35e
commit 9795724476
4 changed files with 14 additions and 2 deletions

View File

@ -4142,8 +4142,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
spin_lock_irq(shost->host_lock); spin_lock_irq(shost->host_lock);
if (vport->fc_rscn_flush) { if (vport->fc_rscn_flush) {
/* Another thread is walking fc_rscn_id_list on this vport */ /* Another thread is walking fc_rscn_id_list on this vport */
spin_unlock_irq(shost->host_lock);
vport->fc_flag |= FC_RSCN_DISCOVERY; vport->fc_flag |= FC_RSCN_DISCOVERY;
spin_unlock_irq(shost->host_lock);
/* Send back ACC */ /* Send back ACC */
lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
return 0; return 0;

View File

@ -1708,7 +1708,9 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
lpfc_vport_set_state(vport, FC_VPORT_FAILED); lpfc_vport_set_state(vport, FC_VPORT_FAILED);
return; return;
} }
spin_lock_irq(&phba->hbalock);
vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI;
spin_unlock_irq(&phba->hbalock);
if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
lpfc_initial_fdisc(vport); lpfc_initial_fdisc(vport);
@ -2269,8 +2271,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
mb->mbxStatus); mb->mbxStatus);
break; break;
} }
spin_lock_irq(&phba->hbalock);
vport->vpi_state &= ~LPFC_VPI_REGISTERED; vport->vpi_state &= ~LPFC_VPI_REGISTERED;
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
spin_unlock_irq(&phba->hbalock);
vport->unreg_vpi_cmpl = VPORT_OK; vport->unreg_vpi_cmpl = VPORT_OK;
mempool_free(pmb, phba->mbox_mem_pool); mempool_free(pmb, phba->mbox_mem_pool);
/* /*
@ -4486,8 +4490,10 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
lpfc_mbx_unreg_vpi(vports[i]); lpfc_mbx_unreg_vpi(vports[i]);
spin_lock_irq(&phba->hbalock);
vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
spin_unlock_irq(&phba->hbalock);
} }
lpfc_destroy_vport_work_array(phba, vports); lpfc_destroy_vport_work_array(phba, vports);

View File

@ -3006,6 +3006,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
struct lpfc_vport *vport; struct lpfc_vport *vport;
struct lpfc_nodelist *ndlp; struct lpfc_nodelist *ndlp;
struct Scsi_Host *shost; struct Scsi_Host *shost;
uint32_t link_state;
phba->fc_eventTag = acqe_fcoe->event_tag; phba->fc_eventTag = acqe_fcoe->event_tag;
phba->fcoe_eventtag = acqe_fcoe->event_tag; phba->fcoe_eventtag = acqe_fcoe->event_tag;
@ -3052,9 +3053,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
break; break;
/* /*
* Currently, driver support only one FCF - so treat this as * Currently, driver support only one FCF - so treat this as
* a link down. * a link down, but save the link state because we don't want
* it to be changed to Link Down unless it is already down.
*/ */
link_state = phba->link_state;
lpfc_linkdown(phba); lpfc_linkdown(phba);
phba->link_state = link_state;
/* Unregister FCF if no devices connected to it */ /* Unregister FCF if no devices connected to it */
lpfc_unregister_unused_fcf(phba); lpfc_unregister_unused_fcf(phba);
break; break;

View File

@ -512,8 +512,10 @@ enable_vport(struct fc_vport *fc_vport)
return VPORT_OK; return VPORT_OK;
} }
spin_lock_irq(&phba->hbalock);
vport->load_flag |= FC_LOADING; vport->load_flag |= FC_LOADING;
vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
spin_unlock_irq(&phba->hbalock);
/* Use the Physical nodes Fabric NDLP to determine if the link is /* Use the Physical nodes Fabric NDLP to determine if the link is
* up and ready to FDISC. * up and ready to FDISC.