diff --git a/qla2x00t-32gbit/qla2x00-target/qla_tgt.c b/qla2x00t-32gbit/qla2x00-target/qla_tgt.c index 03fb20cc8..36b289603 100644 --- a/qla2x00t-32gbit/qla2x00-target/qla_tgt.c +++ b/qla2x00t-32gbit/qla2x00-target/qla_tgt.c @@ -47,9 +47,10 @@ size_t qlt_add_vtarget(u64 port_name, u64 node_name, u64 parent_host) { + struct fc_vport *vport; struct Scsi_Host *shost = NULL; + scsi_qla_host_t *vha = NULL, *npiv_vha; struct qla_tgt *tgt; - scsi_qla_host_t *vha = NULL; struct fc_vport_identifiers vid; uint8_t parent_wwn[WWN_SIZE]; @@ -78,8 +79,14 @@ size_t qlt_add_vtarget(u64 port_name, u64 node_name, u64 parent_host) vid.disable = false; /* always enabled */ /* We only allow support on Channel 0 !!! */ - if (!fc_vport_create(shost, 0, &vid)) + vport = fc_vport_create(shost, 0, &vid); + if (!vport) { + pr_err("fc_vport_create failed for qla2xxx_npiv\n"); return -EINVAL; + } + + npiv_vha = (struct scsi_qla_host *) vport->dd_data; + scsi_host_get(npiv_vha->host); return 0; } diff --git a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c index 5e1e35cb2..b208cc753 100644 --- a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c +++ b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c @@ -1437,6 +1437,39 @@ static void sqa_qla2xxx_remove_target(struct scsi_qla_host *vha) scst_unregister_target(sqa_tgt->scst_tgt); TRACE_EXIT(); } + +static void sqa_qla2xxx_drop_lport(struct qla_tgt *tgt) +{ + struct scsi_qla_host *vha = tgt->vha; + + TRACE_ENTRY(); + + if (vha->vha_tgt.qla_tgt->tgt_stop && + !vha->vha_tgt.qla_tgt->tgt_stopped) { + PRINT_INFO("sqatgt(%ld/%d): calling qlt_stop_phase2.\n", + vha->host_no, vha->vp_idx); + qlt_stop_phase2(vha->vha_tgt.qla_tgt); + } + + qlt_lport_deregister(vha); + + TRACE_EXIT(); +} + +static void sqa_qla2xxx_npiv_drop_lport(struct qla_tgt *tgt) +{ + struct scsi_qla_host *npiv_vha = tgt->vha; + struct qla_hw_data *ha = npiv_vha->hw; + scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); + + TRACE_ENTRY(); + + scsi_host_put(npiv_vha->host); + scsi_host_put(base_vha->host); + + TRACE_EXIT(); +} + /* * Must be called under tgt_host_action_mutex or sqa_unreg_rwsem write * locked. @@ -1450,21 +1483,20 @@ static int sqa_target_release(struct scst_tgt *scst_tgt) TRACE_ENTRY(); if (vha->vha_tgt.target_lport_ptr) { + if (!vha->vha_tgt.qla_tgt->tgt_stop && - !vha->vha_tgt.qla_tgt->tgt_stopped) { + !vha->vha_tgt.qla_tgt->tgt_stopped) { PRINT_INFO("sqatgt(%ld:%d: calling qlt_stop_phase1.\n", - vha->host_no, vha->vp_idx); + vha->host_no, vha->vp_idx); qlt_stop_phase1(vha->vha_tgt.qla_tgt); } - if (vha->vha_tgt.qla_tgt->tgt_stop && - !vha->vha_tgt.qla_tgt->tgt_stopped) { - PRINT_INFO("sqatgt(%ld/%d): calling qlt_stop_phase2.\n", - vha->host_no, vha->vp_idx); - qlt_stop_phase2(vha->vha_tgt.qla_tgt); - } - qlt_lport_deregister(tgt->vha); + if (vha->vp_idx) + sqa_qla2xxx_npiv_drop_lport(tgt); + else + sqa_qla2xxx_drop_lport(tgt); } + scst_tgt_set_tgt_priv(scst_tgt, NULL); mutex_lock(&sqa_mutex); @@ -1473,7 +1505,7 @@ static int sqa_target_release(struct scst_tgt *scst_tgt) mutex_unlock(&sqa_mutex); TRACE(TRACE_MGMT, "sqatgt(%ld/%d): Target release finished sqa_tgt %p", - vha->host_no, tgt->vha->vp_idx, sqa_tgt); + vha->host_no, vha->vp_idx, sqa_tgt); kfree(sqa_tgt);