mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-18 03:01:26 +00:00
Merge branch 'svn-trunk'
This commit is contained in:
@@ -5036,6 +5036,88 @@ static int scst_translate_lun(struct scst_cmd *cmd)
|
||||
return res;
|
||||
}
|
||||
|
||||
static void scst_handle_aca(struct scst_cmd *cmd)
|
||||
{
|
||||
struct scst_order_data *order_data = cmd->cur_order_data;
|
||||
unsigned long flags;
|
||||
|
||||
again:
|
||||
if (likely(!order_data->aca_tgt_dev)) {
|
||||
if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_ACA)) {
|
||||
TRACE_MGMT_DBG("Refusing ACA cmd %p, because there's no ACA, tgt_dev %p",
|
||||
cmd, cmd->tgt_dev);
|
||||
scst_set_cmd_error(cmd,
|
||||
SCST_LOAD_SENSE(scst_sense_invalid_message));
|
||||
scst_set_cmd_abnormal_done_state(cmd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&order_data->sn_lock, flags);
|
||||
if (!order_data->aca_tgt_dev) {
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (order_data->aca_tgt_dev == (unsigned long)cmd->tgt_dev) {
|
||||
if (cmd->queue_type != SCST_CMD_QUEUE_ACA ||
|
||||
order_data->aca_cmd || cmd->dev->tmf_only) {
|
||||
TRACE_DBG("Refusing cmd %p, because ACA active (aca_cmd %p, tgt_dev %p)",
|
||||
cmd, order_data->aca_cmd,
|
||||
cmd->tgt_dev);
|
||||
goto out_unlock_aca_active;
|
||||
} else {
|
||||
TRACE_MGMT_DBG("ACA cmd %p (tgt_dev %p)",
|
||||
cmd, cmd->tgt_dev);
|
||||
order_data->aca_cmd = cmd;
|
||||
/* allow it */
|
||||
}
|
||||
} else {
|
||||
/* Non-faulted I_T nexus */
|
||||
EXTRACHECKS_BUG_ON(cmd->dev->tst != SCST_TST_0_SINGLE_TASK_SET);
|
||||
if (cmd->queue_type == SCST_CMD_QUEUE_ACA) {
|
||||
TRACE_MGMT_DBG("Refusing ACA cmd %p from wrong I_T nexus (aca_tgt_dev %ld, cmd->tgt_dev %p)",
|
||||
cmd, order_data->aca_tgt_dev,
|
||||
cmd->tgt_dev);
|
||||
scst_set_cmd_error(cmd,
|
||||
SCST_LOAD_SENSE(scst_sense_invalid_message));
|
||||
goto out_unlock_aca_active;
|
||||
} else {
|
||||
if (cmd->cdb[0] == PERSISTENT_RESERVE_OUT &&
|
||||
(cmd->cdb[1] & 0x1f) == PR_PREEMPT_AND_ABORT) {
|
||||
TRACE_MGMT_DBG("Allow PR PREEMPT AND ABORT cmd %p during ACA (tgt_dev %p)",
|
||||
cmd, cmd->tgt_dev);
|
||||
/* allow it */
|
||||
} else {
|
||||
TRACE_DBG("Refusing other IT-nexus cmd %p, because ACA active (tgt_dev %p)",
|
||||
cmd, cmd->tgt_dev);
|
||||
if (cmd->cmd_naca) {
|
||||
goto out_unlock_aca_active;
|
||||
} else {
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
scst_set_cmd_error_status(cmd, SAM_STAT_BUSY);
|
||||
goto out_bypass_aca;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd->cmd_aca_allowed = 1;
|
||||
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
|
||||
return;
|
||||
|
||||
out_unlock_aca_active:
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
scst_set_cmd_error_status(cmd, SAM_STAT_ACA_ACTIVE);
|
||||
|
||||
out_bypass_aca:
|
||||
cmd->cmd_aca_allowed = 1; /* for check in scst_pre_xmit_response2() */
|
||||
scst_set_cmd_abnormal_done_state(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* No locks, but might be on IRQ.
|
||||
*
|
||||
@@ -5045,8 +5127,6 @@ static int scst_translate_lun(struct scst_cmd *cmd)
|
||||
static int __scst_init_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = 0;
|
||||
unsigned long flags;
|
||||
struct scst_order_data *order_data;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -5055,8 +5135,6 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
|
||||
int cnt;
|
||||
bool failure = false;
|
||||
|
||||
order_data = cmd->cur_order_data;
|
||||
|
||||
scst_set_cmd_state(cmd, SCST_CMD_STATE_PARSE);
|
||||
|
||||
cnt = atomic_inc_return(&cmd->tgt_dev->tgt_dev_cmd_count);
|
||||
@@ -5102,73 +5180,9 @@ static int __scst_init_cmd(struct scst_cmd *cmd)
|
||||
* queue_type to change it if needed. ToDo.
|
||||
*/
|
||||
scst_pre_parse(cmd);
|
||||
again:
|
||||
if (unlikely(order_data->aca_tgt_dev != 0)) {
|
||||
spin_lock_irqsave(&order_data->sn_lock, flags);
|
||||
|
||||
if (order_data->aca_tgt_dev == 0) {
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (order_data->aca_tgt_dev == (unsigned long)cmd->tgt_dev) {
|
||||
if ((cmd->queue_type != SCST_CMD_QUEUE_ACA) ||
|
||||
(order_data->aca_cmd != NULL) ||
|
||||
cmd->dev->tmf_only) {
|
||||
TRACE_DBG("Refusing cmd %p, because ACA "
|
||||
"active (aca_cmd %p, tgt_dev %p)",
|
||||
cmd, order_data->aca_cmd,
|
||||
cmd->tgt_dev);
|
||||
goto out_unlock_aca_active;
|
||||
} else {
|
||||
TRACE_MGMT_DBG("ACA cmd %p (tgt_dev %p)",
|
||||
cmd, cmd->tgt_dev);
|
||||
order_data->aca_cmd = cmd;
|
||||
/* allow it */
|
||||
}
|
||||
} else {
|
||||
/* Non-faulted I_T nexus */
|
||||
EXTRACHECKS_BUG_ON(cmd->dev->tst != SCST_TST_0_SINGLE_TASK_SET);
|
||||
if (cmd->queue_type == SCST_CMD_QUEUE_ACA) {
|
||||
TRACE_MGMT_DBG("Refusing ACA cmd %p "
|
||||
"from wrong I_T nexus (aca_tgt_dev %ld, "
|
||||
"cmd->tgt_dev %p)", cmd,
|
||||
order_data->aca_tgt_dev, cmd->tgt_dev);
|
||||
scst_set_cmd_error(cmd,
|
||||
SCST_LOAD_SENSE(scst_sense_invalid_message));
|
||||
goto out_unlock_aca_active;
|
||||
} else {
|
||||
if ((cmd->cdb[0] == PERSISTENT_RESERVE_OUT) &&
|
||||
((cmd->cdb[1] & 0x1f) == PR_PREEMPT_AND_ABORT)) {
|
||||
TRACE_MGMT_DBG("Allow PR PREEMPT AND "
|
||||
"ABORT cmd %p during ACA "
|
||||
"(tgt_dev %p)", cmd, cmd->tgt_dev);
|
||||
/* allow it */
|
||||
} else {
|
||||
TRACE_DBG("Refusing other IT-nexus "
|
||||
"cmd %p, because ACA active "
|
||||
"(tgt_dev %p)", cmd, cmd->tgt_dev);
|
||||
if (cmd->cmd_naca)
|
||||
goto out_unlock_aca_active;
|
||||
else {
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
scst_set_cmd_error_status(cmd, SAM_STAT_BUSY);
|
||||
goto out_bypass_aca;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cmd->cmd_aca_allowed = 1;
|
||||
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
} else if (unlikely(cmd->queue_type == SCST_CMD_QUEUE_ACA)) {
|
||||
TRACE_MGMT_DBG("Refusing ACA cmd %p, because there's no ACA, "
|
||||
"tgt_dev %p", cmd, cmd->tgt_dev);
|
||||
scst_set_cmd_error(cmd,
|
||||
SCST_LOAD_SENSE(scst_sense_invalid_message));
|
||||
goto out_abnormal;
|
||||
}
|
||||
scst_handle_aca(cmd);
|
||||
if (cmd->completed)
|
||||
goto out;
|
||||
|
||||
if (!cmd->set_sn_on_restart_cmd) {
|
||||
if (!cmd->tgtt->multithreaded_init_done)
|
||||
@@ -5194,18 +5208,11 @@ out:
|
||||
|
||||
out_busy_bypass_aca:
|
||||
scst_set_busy(cmd);
|
||||
|
||||
out_bypass_aca:
|
||||
cmd->cmd_aca_allowed = 1; /* for check in scst_pre_xmit_response2() */
|
||||
|
||||
out_abnormal:
|
||||
scst_set_cmd_abnormal_done_state(cmd);
|
||||
goto out;
|
||||
|
||||
out_unlock_aca_active:
|
||||
spin_unlock_irqrestore(&order_data->sn_lock, flags);
|
||||
scst_set_cmd_error_status(cmd, SAM_STAT_ACA_ACTIVE);
|
||||
goto out_bypass_aca;
|
||||
}
|
||||
|
||||
/* Called under scst_init_lock and IRQs disabled */
|
||||
|
||||
Reference in New Issue
Block a user