|
|
|
@ -59,6 +59,8 @@ MODULE_PARM_DESC(qlini_mode,
|
|
|
|
|
|
|
|
|
|
int ql2x_ini_mode = QLA2XXX_INI_MODE_EXCLUSIVE;
|
|
|
|
|
|
|
|
|
|
static int temp_sam_status = SAM_STAT_BUSY;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* From scsi/fc/fc_fcp.h
|
|
|
|
|
*/
|
|
|
|
@ -108,6 +110,8 @@ static void qlt_reject_free_srr_imm(struct scsi_qla_host *ha,
|
|
|
|
|
struct qla_tgt_srr_imm *imm, int ha_lock);
|
|
|
|
|
static void qlt_abort_cmd_on_host_reset(struct scsi_qla_host *vha,
|
|
|
|
|
struct qla_tgt_cmd *cmd);
|
|
|
|
|
static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
|
|
|
|
|
struct atio_from_isp *atio, uint16_t status, int qfull);
|
|
|
|
|
/*
|
|
|
|
|
* Global Variables
|
|
|
|
|
*/
|
|
|
|
@ -185,6 +189,27 @@ struct scsi_qla_host *qlt_find_host_by_vp_idx(struct scsi_qla_host *vha,
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline void qlt_incr_num_pend_cmds(struct scsi_qla_host *vha)
|
|
|
|
|
{
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
|
|
|
|
|
|
|
|
|
|
vha->hw->tgt.num_pend_cmds++;
|
|
|
|
|
if (vha->hw->tgt.num_pend_cmds > vha->hw->qla_stats.stat_max_pend_cmds)
|
|
|
|
|
vha->hw->qla_stats.stat_max_pend_cmds =
|
|
|
|
|
vha->hw->tgt.num_pend_cmds;
|
|
|
|
|
spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
|
|
|
|
|
}
|
|
|
|
|
static inline void qlt_decr_num_pend_cmds(struct scsi_qla_host *vha)
|
|
|
|
|
{
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&vha->hw->tgt.q_full_lock, flags);
|
|
|
|
|
vha->hw->tgt.num_pend_cmds--;
|
|
|
|
|
spin_unlock_irqrestore(&vha->hw->tgt.q_full_lock, flags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
|
|
|
|
|
struct atio_from_isp *atio)
|
|
|
|
|
{
|
|
|
|
@ -2683,10 +2708,14 @@ static void qlt_send_term_exchange(struct scsi_qla_host *vha,
|
|
|
|
|
|
|
|
|
|
if (ha_locked) {
|
|
|
|
|
rc = __qlt_send_term_exchange(vha, cmd, atio);
|
|
|
|
|
if (rc == -ENOMEM)
|
|
|
|
|
qlt_alloc_qfull_cmd(vha, atio, 0, 0);
|
|
|
|
|
goto done;
|
|
|
|
|
}
|
|
|
|
|
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
|
|
|
|
|
rc = __qlt_send_term_exchange(vha, cmd, atio);
|
|
|
|
|
if (rc == -ENOMEM)
|
|
|
|
|
qlt_alloc_qfull_cmd(vha, atio, 0, 0);
|
|
|
|
|
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
|
|
|
|
done:
|
|
|
|
|
/*
|
|
|
|
@ -2711,6 +2740,53 @@ done:
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void qlt_init_term_exchange(struct scsi_qla_host *vha)
|
|
|
|
|
{
|
|
|
|
|
struct list_head free_list;
|
|
|
|
|
struct qla_tgt_cmd *cmd, *tcmd;
|
|
|
|
|
|
|
|
|
|
vha->hw->tgt.leak_exchg_thresh_hold =
|
|
|
|
|
(vha->hw->fw_xcb_count/100) * LEAK_EXCHG_THRESH_HOLD_PERCENT;
|
|
|
|
|
|
|
|
|
|
cmd = tcmd = NULL;
|
|
|
|
|
if (!list_empty(&vha->hw->tgt.q_full_list)) {
|
|
|
|
|
INIT_LIST_HEAD(&free_list);
|
|
|
|
|
list_splice_init(&vha->hw->tgt.q_full_list, &free_list);
|
|
|
|
|
|
|
|
|
|
list_for_each_entry_safe(cmd, tcmd, &free_list, cmd_list) {
|
|
|
|
|
list_del(&cmd->cmd_list);
|
|
|
|
|
/* This cmd was never sent to TCM. There is no need
|
|
|
|
|
* to schedule free or call free_cmd
|
|
|
|
|
*/
|
|
|
|
|
qlt_free_cmd(cmd);
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_alloc--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_dropped = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha)
|
|
|
|
|
{
|
|
|
|
|
uint32_t total_leaked;
|
|
|
|
|
|
|
|
|
|
total_leaked = vha->hw->tgt.num_qfull_cmds_dropped;
|
|
|
|
|
|
|
|
|
|
if (vha->hw->tgt.leak_exchg_thresh_hold &&
|
|
|
|
|
(total_leaked > vha->hw->tgt.leak_exchg_thresh_hold)) {
|
|
|
|
|
|
|
|
|
|
ql_dbg(ql_dbg_tgt, vha, 0xe079,
|
|
|
|
|
"Chip reset due to exchange starvation: %d/%d.\n",
|
|
|
|
|
total_leaked, vha->hw->fw_xcb_count);
|
|
|
|
|
|
|
|
|
|
if (IS_P3P_TYPE(vha->hw))
|
|
|
|
|
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
|
|
|
|
|
else
|
|
|
|
|
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
|
|
|
|
|
qla2xxx_wake_dpc(vha);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void qlt_free_cmd(struct qla_tgt_cmd *cmd)
|
|
|
|
|
{
|
|
|
|
|
struct qla_tgt_sess *sess = cmd->sess;
|
|
|
|
@ -2720,6 +2796,9 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
|
|
|
|
|
__func__, &cmd->se_cmd,
|
|
|
|
|
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
|
|
|
|
|
|
|
|
|
|
if (!cmd->q_full)
|
|
|
|
|
qlt_decr_num_pend_cmds(cmd->vha);
|
|
|
|
|
|
|
|
|
|
BUG_ON(cmd->sg_mapped);
|
|
|
|
|
if (unlikely(cmd->free_sg))
|
|
|
|
|
kfree(cmd->sg);
|
|
|
|
@ -3078,7 +3157,7 @@ static void qlt_do_ctio_completion(struct scsi_qla_host *vha, uint32_t handle,
|
|
|
|
|
* level.
|
|
|
|
|
*/
|
|
|
|
|
if ((cmd->state != QLA_TGT_STATE_NEED_DATA) &&
|
|
|
|
|
(cmd->state != QLA_TGT_STATE_ABORTED)) {
|
|
|
|
|
(cmd->state != QLA_TGT_STATE_ABORTED)) {
|
|
|
|
|
if (qlt_term_ctio_exchange(vha, ctio, cmd, status))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -3114,6 +3193,7 @@ skip_term:
|
|
|
|
|
dump_stack();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ha->tgt.tgt_ops->free_cmd(cmd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -3211,6 +3291,8 @@ out_term:
|
|
|
|
|
*/
|
|
|
|
|
spin_lock_irqsave(&ha->hardware_lock, flags);
|
|
|
|
|
qlt_send_term_exchange(vha, NULL, &cmd->atio, 1);
|
|
|
|
|
|
|
|
|
|
qlt_decr_num_pend_cmds(vha);
|
|
|
|
|
percpu_ida_free(&sess->se_sess->sess_tag_pool, cmd->se_cmd.map_tag);
|
|
|
|
|
ha->tgt.tgt_ops->put_sess(sess);
|
|
|
|
|
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
|
|
|
@ -3241,6 +3323,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha,
|
|
|
|
|
memcpy(&cmd->atio, atio, sizeof(*atio));
|
|
|
|
|
cmd->state = QLA_TGT_STATE_NEW;
|
|
|
|
|
cmd->tgt = vha->vha_tgt.qla_tgt;
|
|
|
|
|
qlt_incr_num_pend_cmds(vha);
|
|
|
|
|
cmd->vha = vha;
|
|
|
|
|
cmd->se_cmd.map_tag = tag;
|
|
|
|
|
cmd->sess = sess;
|
|
|
|
@ -4184,7 +4267,7 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha,
|
|
|
|
|
* ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
|
|
|
|
|
* This function sends busy to ISP 2xxx or 24xx.
|
|
|
|
|
*/
|
|
|
|
|
static void qlt_send_busy(struct scsi_qla_host *vha,
|
|
|
|
|
static int __qlt_send_busy(struct scsi_qla_host *vha,
|
|
|
|
|
struct atio_from_isp *atio, uint16_t status)
|
|
|
|
|
{
|
|
|
|
|
struct ctio7_to_24xx *ctio24;
|
|
|
|
@ -4196,7 +4279,7 @@ static void qlt_send_busy(struct scsi_qla_host *vha,
|
|
|
|
|
atio->u.isp24.fcp_hdr.s_id);
|
|
|
|
|
if (!sess) {
|
|
|
|
|
qlt_send_term_exchange(vha, NULL, atio, 1);
|
|
|
|
|
return;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
/* Sending marker isn't necessary, since we called from ISR */
|
|
|
|
|
|
|
|
|
@ -4205,7 +4288,7 @@ static void qlt_send_busy(struct scsi_qla_host *vha,
|
|
|
|
|
ql_dbg(ql_dbg_io, vha, 0x3063,
|
|
|
|
|
"qla_target(%d): %s failed: unable to allocate "
|
|
|
|
|
"request packet", vha->vp_idx, __func__);
|
|
|
|
|
return;
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pkt->entry_count = 1;
|
|
|
|
@ -4237,6 +4320,189 @@ static void qlt_send_busy(struct scsi_qla_host *vha,
|
|
|
|
|
ctio24->u.status1.scsi_status |= SS_RESIDUAL_UNDER;
|
|
|
|
|
|
|
|
|
|
qla2x00_start_iocbs(vha, vha->req);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* This routine is used to allocate a command for either a QFull condition
|
|
|
|
|
* (ie reply SAM_STAT_BUSY) or to terminate an exchange that did not go
|
|
|
|
|
* out previously.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
|
|
|
|
|
struct atio_from_isp *atio, uint16_t status, int qfull)
|
|
|
|
|
{
|
|
|
|
|
struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
|
|
|
|
|
struct qla_hw_data *ha = vha->hw;
|
|
|
|
|
struct qla_tgt_sess *sess;
|
|
|
|
|
struct se_session *se_sess;
|
|
|
|
|
struct qla_tgt_cmd *cmd;
|
|
|
|
|
int tag;
|
|
|
|
|
|
|
|
|
|
if (unlikely(tgt->tgt_stop)) {
|
|
|
|
|
ql_dbg(ql_dbg_io, vha, 0x300a,
|
|
|
|
|
"New command while device %p is shutting down\n", tgt);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((vha->hw->tgt.num_qfull_cmds_alloc + 1) > MAX_QFULL_CMDS_ALLOC) {
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_dropped++;
|
|
|
|
|
if (vha->hw->tgt.num_qfull_cmds_dropped >
|
|
|
|
|
vha->hw->qla_stats.stat_max_qfull_cmds_dropped)
|
|
|
|
|
vha->hw->qla_stats.stat_max_qfull_cmds_dropped =
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_dropped;
|
|
|
|
|
|
|
|
|
|
ql_dbg(ql_dbg_io, vha, 0x3068,
|
|
|
|
|
"qla_target(%d): %s: QFull CMD dropped[%d]\n",
|
|
|
|
|
vha->vp_idx, __func__,
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_dropped);
|
|
|
|
|
|
|
|
|
|
qlt_chk_exch_leak_thresh_hold(vha);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sess = ha->tgt.tgt_ops->find_sess_by_s_id
|
|
|
|
|
(vha, atio->u.isp24.fcp_hdr.s_id);
|
|
|
|
|
if (!sess)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
se_sess = sess->se_sess;
|
|
|
|
|
|
|
|
|
|
tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING);
|
|
|
|
|
if (tag < 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
cmd = &((struct qla_tgt_cmd *)se_sess->sess_cmd_map)[tag];
|
|
|
|
|
if (!cmd) {
|
|
|
|
|
ql_dbg(ql_dbg_io, vha, 0x3009,
|
|
|
|
|
"qla_target(%d): %s: Allocation of cmd failed\n",
|
|
|
|
|
vha->vp_idx, __func__);
|
|
|
|
|
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_dropped++;
|
|
|
|
|
if (vha->hw->tgt.num_qfull_cmds_dropped >
|
|
|
|
|
vha->hw->qla_stats.stat_max_qfull_cmds_dropped)
|
|
|
|
|
vha->hw->qla_stats.stat_max_qfull_cmds_dropped =
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_dropped;
|
|
|
|
|
|
|
|
|
|
qlt_chk_exch_leak_thresh_hold(vha);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
memset(cmd, 0, sizeof(struct qla_tgt_cmd));
|
|
|
|
|
|
|
|
|
|
qlt_incr_num_pend_cmds(vha);
|
|
|
|
|
INIT_LIST_HEAD(&cmd->cmd_list);
|
|
|
|
|
memcpy(&cmd->atio, atio, sizeof(*atio));
|
|
|
|
|
|
|
|
|
|
cmd->tgt = vha->vha_tgt.qla_tgt;
|
|
|
|
|
cmd->vha = vha;
|
|
|
|
|
cmd->reset_count = vha->hw->chip_reset;
|
|
|
|
|
cmd->q_full = 1;
|
|
|
|
|
|
|
|
|
|
if (qfull) {
|
|
|
|
|
cmd->q_full = 1;
|
|
|
|
|
/* NOTE: borrowing the state field to carry the status */
|
|
|
|
|
cmd->state = status;
|
|
|
|
|
} else
|
|
|
|
|
cmd->term_exchg = 1;
|
|
|
|
|
|
|
|
|
|
list_add_tail(&cmd->cmd_list, &vha->hw->tgt.q_full_list);
|
|
|
|
|
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_alloc++;
|
|
|
|
|
if (vha->hw->tgt.num_qfull_cmds_alloc >
|
|
|
|
|
vha->hw->qla_stats.stat_max_qfull_cmds_alloc)
|
|
|
|
|
vha->hw->qla_stats.stat_max_qfull_cmds_alloc =
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_alloc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
qlt_free_qfull_cmds(struct scsi_qla_host *vha)
|
|
|
|
|
{
|
|
|
|
|
struct qla_hw_data *ha = vha->hw;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
struct qla_tgt_cmd *cmd, *tcmd;
|
|
|
|
|
struct list_head free_list;
|
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
|
|
if (list_empty(&ha->tgt.q_full_list))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
INIT_LIST_HEAD(&free_list);
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
|
|
|
|
|
|
|
|
|
|
if (list_empty(&ha->tgt.q_full_list)) {
|
|
|
|
|
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list_for_each_entry_safe(cmd, tcmd, &ha->tgt.q_full_list, cmd_list) {
|
|
|
|
|
if (cmd->q_full)
|
|
|
|
|
/* cmd->state is a borrowed field to hold status */
|
|
|
|
|
rc = __qlt_send_busy(vha, &cmd->atio, cmd->state);
|
|
|
|
|
else if (cmd->term_exchg)
|
|
|
|
|
rc = __qlt_send_term_exchange(vha, NULL, &cmd->atio);
|
|
|
|
|
|
|
|
|
|
if (rc == -ENOMEM)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
if (cmd->q_full)
|
|
|
|
|
ql_dbg(ql_dbg_io, vha, 0x3006,
|
|
|
|
|
"%s: busy sent for ox_id[%04x]\n", __func__,
|
|
|
|
|
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
|
|
|
|
|
else if (cmd->term_exchg)
|
|
|
|
|
ql_dbg(ql_dbg_io, vha, 0x3007,
|
|
|
|
|
"%s: Term exchg sent for ox_id[%04x]\n", __func__,
|
|
|
|
|
be16_to_cpu(cmd->atio.u.isp24.fcp_hdr.ox_id));
|
|
|
|
|
else
|
|
|
|
|
ql_dbg(ql_dbg_io, vha, 0x3008,
|
|
|
|
|
"%s: Unexpected cmd in QFull list %p\n", __func__,
|
|
|
|
|
cmd);
|
|
|
|
|
|
|
|
|
|
list_del(&cmd->cmd_list);
|
|
|
|
|
list_add_tail(&cmd->cmd_list, &free_list);
|
|
|
|
|
|
|
|
|
|
/* piggy back on hardware_lock for protection */
|
|
|
|
|
vha->hw->tgt.num_qfull_cmds_alloc--;
|
|
|
|
|
}
|
|
|
|
|
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
|
|
|
|
|
|
|
|
|
|
cmd = NULL;
|
|
|
|
|
|
|
|
|
|
list_for_each_entry_safe(cmd, tcmd, &free_list, cmd_list) {
|
|
|
|
|
list_del(&cmd->cmd_list);
|
|
|
|
|
/* This cmd was never sent to TCM. There is no need
|
|
|
|
|
* to schedule free or call free_cmd
|
|
|
|
|
*/
|
|
|
|
|
qlt_free_cmd(cmd);
|
|
|
|
|
}
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
qlt_send_busy(struct scsi_qla_host *vha,
|
|
|
|
|
struct atio_from_isp *atio, uint16_t status)
|
|
|
|
|
{
|
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
|
|
rc = __qlt_send_busy(vha, atio, status);
|
|
|
|
|
if (rc == -ENOMEM)
|
|
|
|
|
qlt_alloc_qfull_cmd(vha, atio, status, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha,
|
|
|
|
|
struct atio_from_isp *atio)
|
|
|
|
|
{
|
|
|
|
|
struct qla_hw_data *ha = vha->hw;
|
|
|
|
|
uint16_t status;
|
|
|
|
|
|
|
|
|
|
if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
status = temp_sam_status;
|
|
|
|
|
qlt_send_busy(vha, atio, status);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* ha->hardware_lock supposed to be held on entry */
|
|
|
|
@ -4271,10 +4537,19 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha,
|
|
|
|
|
qlt_send_busy(vha, atio, SAM_STAT_TASK_SET_FULL);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (likely(atio->u.isp24.fcp_cmnd.task_mgmt_flags == 0)) {
|
|
|
|
|
rc = qlt_chk_qfull_thresh_hold(vha, atio);
|
|
|
|
|
if (rc != 0) {
|
|
|
|
|
tgt->irq_cmd_count--;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
rc = qlt_handle_cmd_for_atio(vha, atio);
|
|
|
|
|
else
|
|
|
|
|
} else {
|
|
|
|
|
rc = qlt_handle_task_mgmt(vha, atio);
|
|
|
|
|
}
|
|
|
|
|
if (unlikely(rc != 0)) {
|
|
|
|
|
if (rc == -ESRCH) {
|
|
|
|
|
#if 1 /* With TERM EXCHANGE some FC cards refuse to boot */
|
|
|
|
@ -4369,6 +4644,12 @@ static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = qlt_chk_qfull_thresh_hold(vha, atio);
|
|
|
|
|
if (rc != 0) {
|
|
|
|
|
tgt->irq_cmd_count--;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = qlt_handle_cmd_for_atio(vha, atio);
|
|
|
|
|
if (unlikely(rc != 0)) {
|
|
|
|
|
if (rc == -ESRCH) {
|
|
|
|
@ -4906,6 +5187,10 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha)
|
|
|
|
|
qlt_release(vha->vha_tgt.qla_tgt);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* free left over qfull cmds */
|
|
|
|
|
qlt_init_term_exchange(vha);
|
|
|
|
|
|
|
|
|
|
mutex_lock(&qla_tgt_mutex);
|
|
|
|
|
list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry);
|
|
|
|
|
mutex_unlock(&qla_tgt_mutex);
|
|
|
|
|