aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_target.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/qla2xxx/qla_target.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 2eb97d7e8d12..0cb73074c199 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -790,17 +790,32 @@ static inline int test_tgt_sess_count(struct qla_tgt *tgt)
790} 790}
791 791
792/* Called by tcm_qla2xxx configfs code */ 792/* Called by tcm_qla2xxx configfs code */
793void qlt_stop_phase1(struct qla_tgt *tgt) 793int qlt_stop_phase1(struct qla_tgt *tgt)
794{ 794{
795 struct scsi_qla_host *vha = tgt->vha; 795 struct scsi_qla_host *vha = tgt->vha;
796 struct qla_hw_data *ha = tgt->ha; 796 struct qla_hw_data *ha = tgt->ha;
797 unsigned long flags; 797 unsigned long flags;
798 798
799 mutex_lock(&qla_tgt_mutex);
800 if (!vha->fc_vport) {
801 struct Scsi_Host *sh = vha->host;
802 struct fc_host_attrs *fc_host = shost_to_fc_host(sh);
803 bool npiv_vports;
804
805 spin_lock_irqsave(sh->host_lock, flags);
806 npiv_vports = (fc_host->npiv_vports_inuse);
807 spin_unlock_irqrestore(sh->host_lock, flags);
808
809 if (npiv_vports) {
810 mutex_unlock(&qla_tgt_mutex);
811 return -EPERM;
812 }
813 }
799 if (tgt->tgt_stop || tgt->tgt_stopped) { 814 if (tgt->tgt_stop || tgt->tgt_stopped) {
800 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e, 815 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04e,
801 "Already in tgt->tgt_stop or tgt_stopped state\n"); 816 "Already in tgt->tgt_stop or tgt_stopped state\n");
802 dump_stack(); 817 mutex_unlock(&qla_tgt_mutex);
803 return; 818 return -EPERM;
804 } 819 }
805 820
806 ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n", 821 ql_dbg(ql_dbg_tgt, vha, 0xe003, "Stopping target for host %ld(%p)\n",
@@ -815,6 +830,7 @@ void qlt_stop_phase1(struct qla_tgt *tgt)
815 qlt_clear_tgt_db(tgt, true); 830 qlt_clear_tgt_db(tgt, true);
816 spin_unlock_irqrestore(&ha->hardware_lock, flags); 831 spin_unlock_irqrestore(&ha->hardware_lock, flags);
817 mutex_unlock(&vha->vha_tgt.tgt_mutex); 832 mutex_unlock(&vha->vha_tgt.tgt_mutex);
833 mutex_unlock(&qla_tgt_mutex);
818 834
819 flush_delayed_work(&tgt->sess_del_work); 835 flush_delayed_work(&tgt->sess_del_work);
820 836
@@ -841,6 +857,7 @@ void qlt_stop_phase1(struct qla_tgt *tgt)
841 857
842 /* Wait for sessions to clear out (just in case) */ 858 /* Wait for sessions to clear out (just in case) */
843 wait_event(tgt->waitQ, test_tgt_sess_count(tgt)); 859 wait_event(tgt->waitQ, test_tgt_sess_count(tgt));
860 return 0;
844} 861}
845EXPORT_SYMBOL(qlt_stop_phase1); 862EXPORT_SYMBOL(qlt_stop_phase1);
846 863
@@ -3185,7 +3202,8 @@ restart:
3185 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c, 3202 ql_dbg(ql_dbg_tgt_mgt, vha, 0xf02c,
3186 "SRR cmd %p (se_cmd %p, tag %d, op %x), " 3203 "SRR cmd %p (se_cmd %p, tag %d, op %x), "
3187 "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag, 3204 "sg_cnt=%d, offset=%d", cmd, &cmd->se_cmd, cmd->tag,
3188 se_cmd->t_task_cdb[0], cmd->sg_cnt, cmd->offset); 3205 se_cmd->t_task_cdb ? se_cmd->t_task_cdb[0] : 0,
3206 cmd->sg_cnt, cmd->offset);
3189 3207
3190 qlt_handle_srr(vha, sctio, imm); 3208 qlt_handle_srr(vha, sctio, imm);
3191 3209
@@ -4181,6 +4199,9 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha)
4181 tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX; 4199 tgt->datasegs_per_cmd = QLA_TGT_DATASEGS_PER_CMD_24XX;
4182 tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX; 4200 tgt->datasegs_per_cont = QLA_TGT_DATASEGS_PER_CONT_24XX;
4183 4201
4202 if (base_vha->fc_vport)
4203 return 0;
4204
4184 mutex_lock(&qla_tgt_mutex); 4205 mutex_lock(&qla_tgt_mutex);
4185 list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist); 4206 list_add_tail(&tgt->tgt_list_entry, &qla_tgt_glist);
4186 mutex_unlock(&qla_tgt_mutex); 4207 mutex_unlock(&qla_tgt_mutex);
@@ -4194,6 +4215,10 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha)
4194 if (!vha->vha_tgt.qla_tgt) 4215 if (!vha->vha_tgt.qla_tgt)
4195 return 0; 4216 return 0;
4196 4217
4218 if (vha->fc_vport) {
4219 qlt_release(vha->vha_tgt.qla_tgt);
4220 return 0;
4221 }
4197 mutex_lock(&qla_tgt_mutex); 4222 mutex_lock(&qla_tgt_mutex);
4198 list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); 4223 list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry);
4199 mutex_unlock(&qla_tgt_mutex); 4224 mutex_unlock(&qla_tgt_mutex);
@@ -4265,6 +4290,12 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn,
4265 spin_unlock_irqrestore(&ha->hardware_lock, flags); 4290 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4266 continue; 4291 continue;
4267 } 4292 }
4293 if (tgt->tgt_stop) {
4294 pr_debug("MODE_TARGET in shutdown on qla2xxx(%d)\n",
4295 host->host_no);
4296 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4297 continue;
4298 }
4268 spin_unlock_irqrestore(&ha->hardware_lock, flags); 4299 spin_unlock_irqrestore(&ha->hardware_lock, flags);
4269 4300
4270 if (!scsi_host_get(host)) { 4301 if (!scsi_host_get(host)) {
@@ -4279,12 +4310,11 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn,
4279 scsi_host_put(host); 4310 scsi_host_put(host);
4280 continue; 4311 continue;
4281 } 4312 }
4282 mutex_unlock(&qla_tgt_mutex);
4283
4284 rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); 4313 rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn);
4285 if (rc != 0) 4314 if (rc != 0)
4286 scsi_host_put(host); 4315 scsi_host_put(host);
4287 4316
4317 mutex_unlock(&qla_tgt_mutex);
4288 return rc; 4318 return rc;
4289 } 4319 }
4290 mutex_unlock(&qla_tgt_mutex); 4320 mutex_unlock(&qla_tgt_mutex);