[SCSI] lpfc 8.3.39: Fixed VPI allocation issues after firmware dump is performed
Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
96b04db9f2
commit
16a3a20842
|
@ -2796,7 +2796,19 @@ void
|
||||||
lpfc_issue_init_vpi(struct lpfc_vport *vport)
|
lpfc_issue_init_vpi(struct lpfc_vport *vport)
|
||||||
{
|
{
|
||||||
LPFC_MBOXQ_t *mboxq;
|
LPFC_MBOXQ_t *mboxq;
|
||||||
int rc;
|
int rc, vpi;
|
||||||
|
|
||||||
|
if ((vport->port_type != LPFC_PHYSICAL_PORT) && (!vport->vpi)) {
|
||||||
|
vpi = lpfc_alloc_vpi(vport->phba);
|
||||||
|
if (!vpi) {
|
||||||
|
lpfc_printf_vlog(vport, KERN_ERR,
|
||||||
|
LOG_MBOX,
|
||||||
|
"3303 Failed to obtain vport vpi\n");
|
||||||
|
lpfc_vport_set_state(vport, FC_VPORT_FAILED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vport->vpi = vpi;
|
||||||
|
}
|
||||||
|
|
||||||
mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL);
|
mboxq = mempool_alloc(vport->phba->mbox_mem_pool, GFP_KERNEL);
|
||||||
if (!mboxq) {
|
if (!mboxq) {
|
||||||
|
|
|
@ -2633,6 +2633,7 @@ lpfc_online(struct lpfc_hba *phba)
|
||||||
struct lpfc_vport *vport;
|
struct lpfc_vport *vport;
|
||||||
struct lpfc_vport **vports;
|
struct lpfc_vport **vports;
|
||||||
int i;
|
int i;
|
||||||
|
bool vpis_cleared = false;
|
||||||
|
|
||||||
if (!phba)
|
if (!phba)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2656,6 +2657,10 @@ lpfc_online(struct lpfc_hba *phba)
|
||||||
lpfc_unblock_mgmt_io(phba);
|
lpfc_unblock_mgmt_io(phba);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
spin_lock_irq(&phba->hbalock);
|
||||||
|
if (!phba->sli4_hba.max_cfg_param.vpi_used)
|
||||||
|
vpis_cleared = true;
|
||||||
|
spin_unlock_irq(&phba->hbalock);
|
||||||
} else {
|
} else {
|
||||||
if (lpfc_sli_hba_setup(phba)) { /* Initialize SLI2/SLI3 HBA */
|
if (lpfc_sli_hba_setup(phba)) { /* Initialize SLI2/SLI3 HBA */
|
||||||
lpfc_unblock_mgmt_io(phba);
|
lpfc_unblock_mgmt_io(phba);
|
||||||
|
@ -2672,8 +2677,13 @@ lpfc_online(struct lpfc_hba *phba)
|
||||||
vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
|
vports[i]->fc_flag &= ~FC_OFFLINE_MODE;
|
||||||
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
|
if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
|
||||||
vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
|
vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
|
||||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||||
vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
|
vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
|
||||||
|
if ((vpis_cleared) &&
|
||||||
|
(vports[i]->port_type !=
|
||||||
|
LPFC_PHYSICAL_PORT))
|
||||||
|
vports[i]->vpi = 0;
|
||||||
|
}
|
||||||
spin_unlock_irq(shost->host_lock);
|
spin_unlock_irq(shost->host_lock);
|
||||||
}
|
}
|
||||||
lpfc_destroy_vport_work_array(phba, vports);
|
lpfc_destroy_vport_work_array(phba, vports);
|
||||||
|
|
|
@ -5511,6 +5511,7 @@ lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type)
|
||||||
list_del_init(&rsrc_blk->list);
|
list_del_init(&rsrc_blk->list);
|
||||||
kfree(rsrc_blk);
|
kfree(rsrc_blk);
|
||||||
}
|
}
|
||||||
|
phba->sli4_hba.max_cfg_param.vpi_used = 0;
|
||||||
break;
|
break;
|
||||||
case LPFC_RSC_TYPE_FCOE_XRI:
|
case LPFC_RSC_TYPE_FCOE_XRI:
|
||||||
kfree(phba->sli4_hba.xri_bmask);
|
kfree(phba->sli4_hba.xri_bmask);
|
||||||
|
@ -5811,6 +5812,7 @@ lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *phba)
|
||||||
lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI);
|
lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI);
|
||||||
} else {
|
} else {
|
||||||
kfree(phba->vpi_bmask);
|
kfree(phba->vpi_bmask);
|
||||||
|
phba->sli4_hba.max_cfg_param.vpi_used = 0;
|
||||||
kfree(phba->vpi_ids);
|
kfree(phba->vpi_ids);
|
||||||
bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
|
bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
|
||||||
kfree(phba->sli4_hba.xri_bmask);
|
kfree(phba->sli4_hba.xri_bmask);
|
||||||
|
|
|
@ -80,7 +80,7 @@ inline void lpfc_vport_set_state(struct lpfc_vport *vport,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
int
|
||||||
lpfc_alloc_vpi(struct lpfc_hba *phba)
|
lpfc_alloc_vpi(struct lpfc_hba *phba)
|
||||||
{
|
{
|
||||||
unsigned long vpi;
|
unsigned long vpi;
|
||||||
|
@ -568,6 +568,7 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
||||||
struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
|
struct lpfc_vport *vport = *(struct lpfc_vport **)fc_vport->dd_data;
|
||||||
struct lpfc_hba *phba = vport->phba;
|
struct lpfc_hba *phba = vport->phba;
|
||||||
long timeout;
|
long timeout;
|
||||||
|
bool ns_ndlp_referenced = false;
|
||||||
|
|
||||||
if (vport->port_type == LPFC_PHYSICAL_PORT) {
|
if (vport->port_type == LPFC_PHYSICAL_PORT) {
|
||||||
lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
|
lpfc_printf_vlog(vport, KERN_ERR, LOG_VPORT,
|
||||||
|
@ -628,6 +629,18 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
||||||
|
|
||||||
lpfc_debugfs_terminate(vport);
|
lpfc_debugfs_terminate(vport);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The call to fc_remove_host might release the NameServer ndlp. Since
|
||||||
|
* we might need to use the ndlp to send the DA_ID CT command,
|
||||||
|
* increment the reference for the NameServer ndlp to prevent it from
|
||||||
|
* being released.
|
||||||
|
*/
|
||||||
|
ndlp = lpfc_findnode_did(vport, NameServer_DID);
|
||||||
|
if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
|
||||||
|
lpfc_nlp_get(ndlp);
|
||||||
|
ns_ndlp_referenced = true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove FC host and then SCSI host with the vport */
|
/* Remove FC host and then SCSI host with the vport */
|
||||||
fc_remove_host(lpfc_shost_from_vport(vport));
|
fc_remove_host(lpfc_shost_from_vport(vport));
|
||||||
scsi_remove_host(lpfc_shost_from_vport(vport));
|
scsi_remove_host(lpfc_shost_from_vport(vport));
|
||||||
|
@ -734,6 +747,16 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
|
||||||
lpfc_discovery_wait(vport);
|
lpfc_discovery_wait(vport);
|
||||||
|
|
||||||
skip_logo:
|
skip_logo:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the NameServer ndlp has been incremented to allow the DA_ID CT
|
||||||
|
* command to be sent, decrement the ndlp now.
|
||||||
|
*/
|
||||||
|
if (ns_ndlp_referenced) {
|
||||||
|
ndlp = lpfc_findnode_did(vport, NameServer_DID);
|
||||||
|
lpfc_nlp_put(ndlp);
|
||||||
|
}
|
||||||
|
|
||||||
lpfc_cleanup(vport);
|
lpfc_cleanup(vport);
|
||||||
lpfc_sli_host_down(vport);
|
lpfc_sli_host_down(vport);
|
||||||
|
|
||||||
|
|
|
@ -90,6 +90,7 @@ int lpfc_vport_getinfo(struct Scsi_Host *, struct vport_info *);
|
||||||
int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint);
|
int lpfc_vport_tgt_remove(struct Scsi_Host *, uint, uint);
|
||||||
struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *);
|
struct lpfc_vport **lpfc_create_vport_work_array(struct lpfc_hba *);
|
||||||
void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **);
|
void lpfc_destroy_vport_work_array(struct lpfc_hba *, struct lpfc_vport **);
|
||||||
|
int lpfc_alloc_vpi(struct lpfc_hba *phba);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* queuecommand VPORT-specific return codes. Specified in the host byte code.
|
* queuecommand VPORT-specific return codes. Specified in the host byte code.
|
||||||
|
|
Loading…
Reference in a new issue