mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 09:11:27 +00:00
Fexes for processing internal REQUEST SENSE with scst_user handler
git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@688 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -104,10 +104,13 @@ typedef _Bool bool;
|
||||
/* Target driver's xmit_response() is going to be called */
|
||||
#define SCST_CMD_STATE_XMIT_RESP 12
|
||||
|
||||
/* The cmd finished */
|
||||
/* Cmd finished */
|
||||
#define SCST_CMD_STATE_FINISHED 13
|
||||
|
||||
#define SCST_CMD_STATE_LAST_ACTIVE (SCST_CMD_STATE_FINISHED+100)
|
||||
/* Internal cmd finished */
|
||||
#define SCST_CMD_STATE_FINISHED_INTERNAL 14
|
||||
|
||||
#define SCST_CMD_STATE_LAST_ACTIVE (SCST_CMD_STATE_FINISHED_INTERNAL+100)
|
||||
|
||||
/* A cmd is created, but scst_cmd_init_done() not called */
|
||||
#define SCST_CMD_STATE_INIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+1)
|
||||
|
||||
@@ -280,6 +280,7 @@ void scst_set_cmd_abnormal_done_state(struct scst_cmd *cmd)
|
||||
case SCST_CMD_STATE_PRE_XMIT_RESP:
|
||||
case SCST_CMD_STATE_XMIT_RESP:
|
||||
case SCST_CMD_STATE_FINISHED:
|
||||
case SCST_CMD_STATE_FINISHED_INTERNAL:
|
||||
case SCST_CMD_STATE_XMIT_WAIT:
|
||||
PRINT_CRIT_ERROR("Wrong cmd state %x (cmd %p, op %x)",
|
||||
cmd->state, cmd, cmd->cdb[0]);
|
||||
@@ -1042,6 +1043,10 @@ static struct scst_cmd *scst_create_prepare_internal_cmd(
|
||||
res->orig_cmd = orig_cmd;
|
||||
res->bufflen = bufsize;
|
||||
|
||||
scst_sess_get(res->sess);
|
||||
if (res->tgt_dev != NULL)
|
||||
__scst_get(0);
|
||||
|
||||
res->state = SCST_CMD_STATE_PRE_PARSE;
|
||||
|
||||
out:
|
||||
@@ -1049,16 +1054,6 @@ out:
|
||||
return res;
|
||||
}
|
||||
|
||||
static void scst_free_internal_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
TRACE_ENTRY();
|
||||
|
||||
__scst_cmd_put(cmd);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
int scst_prepare_request_sense(struct scst_cmd *orig_cmd)
|
||||
{
|
||||
int res = 0;
|
||||
@@ -1088,11 +1083,11 @@ int scst_prepare_request_sense(struct scst_cmd *orig_cmd)
|
||||
rs_cmd->expected_values_set = 1;
|
||||
|
||||
TRACE(TRACE_MGMT_MINOR, "Adding REQUEST SENSE cmd %p to head of active "
|
||||
"cmd list ", rs_cmd);
|
||||
"cmd list", rs_cmd);
|
||||
spin_lock_irq(&rs_cmd->cmd_lists->cmd_list_lock);
|
||||
list_add(&rs_cmd->cmd_list_entry, &rs_cmd->cmd_lists->active_cmd_list);
|
||||
spin_unlock_irq(&rs_cmd->cmd_lists->cmd_list_lock);
|
||||
wake_up(&rs_cmd->cmd_lists->cmd_list_waitQ);
|
||||
spin_unlock_irq(&rs_cmd->cmd_lists->cmd_list_lock);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
@@ -1104,7 +1099,7 @@ out_error:
|
||||
#undef sbuf_size
|
||||
}
|
||||
|
||||
struct scst_cmd *scst_complete_request_sense(struct scst_cmd *req_cmd)
|
||||
static void scst_complete_request_sense(struct scst_cmd *req_cmd)
|
||||
{
|
||||
struct scst_cmd *orig_cmd = req_cmd->orig_cmd;
|
||||
uint8_t *buf;
|
||||
@@ -1132,10 +1127,34 @@ struct scst_cmd *scst_complete_request_sense(struct scst_cmd *req_cmd)
|
||||
if (len > 0)
|
||||
scst_put_buf(req_cmd, buf);
|
||||
|
||||
scst_free_internal_cmd(req_cmd);
|
||||
TRACE(TRACE_MGMT_MINOR, "Adding orig cmd %p to head of active "
|
||||
"cmd list", orig_cmd);
|
||||
spin_lock_irq(&orig_cmd->cmd_lists->cmd_list_lock);
|
||||
list_add(&orig_cmd->cmd_list_entry, &orig_cmd->cmd_lists->active_cmd_list);
|
||||
wake_up(&orig_cmd->cmd_lists->cmd_list_waitQ);
|
||||
spin_unlock_irq(&orig_cmd->cmd_lists->cmd_list_lock);
|
||||
|
||||
TRACE_EXIT_HRES((unsigned long)orig_cmd);
|
||||
return orig_cmd;
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
int scst_finish_internal_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
int res;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
sBUG_ON(!cmd->internal);
|
||||
|
||||
if (cmd->cdb[0] == REQUEST_SENSE)
|
||||
scst_complete_request_sense(cmd);
|
||||
|
||||
__scst_cmd_put(cmd);
|
||||
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
|
||||
TRACE_EXIT_HRES(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18)
|
||||
@@ -1515,13 +1534,6 @@ void scst_free_cmd(struct scst_cmd *cmd)
|
||||
if (!cmd->tgt_data_buf_alloced)
|
||||
scst_check_restore_sg_buff(cmd);
|
||||
|
||||
if (unlikely(cmd->internal)) {
|
||||
if (cmd->bufflen > 0)
|
||||
scst_release_space(cmd);
|
||||
scst_destroy_cmd(cmd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd->tgtt->on_free_cmd != NULL) {
|
||||
TRACE_DBG("Calling target's on_free_cmd(%p)", cmd);
|
||||
cmd->tgtt->on_free_cmd(cmd);
|
||||
@@ -1549,7 +1561,7 @@ void scst_free_cmd(struct scst_cmd *cmd)
|
||||
|
||||
if (likely(cmd->tgt_dev != NULL)) {
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
if (unlikely(!cmd->sent_for_exec)) {
|
||||
if (unlikely(!cmd->sent_for_exec) && !cmd->internal) {
|
||||
PRINT_ERROR("Finishing not executed cmd %p (opcode "
|
||||
"%d, target %s, lun %lld, sn %ld, expected_sn %ld)",
|
||||
cmd, cmd->cdb[0], cmd->tgtt->name,
|
||||
@@ -1572,7 +1584,6 @@ void scst_free_cmd(struct scst_cmd *cmd)
|
||||
if (likely(destroy))
|
||||
scst_destroy_put_cmd(cmd);
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -261,7 +261,7 @@ int scst_acg_add_name(struct scst_acg *acg, const char *name);
|
||||
int scst_acg_remove_name(struct scst_acg *acg, const char *name);
|
||||
|
||||
int scst_prepare_request_sense(struct scst_cmd *orig_cmd);
|
||||
struct scst_cmd *scst_complete_request_sense(struct scst_cmd *cmd);
|
||||
int scst_finish_internal_cmd(struct scst_cmd *cmd);
|
||||
|
||||
int scst_assign_dev_handler(struct scst_device *dev,
|
||||
struct scst_dev_type *handler);
|
||||
|
||||
@@ -645,6 +645,7 @@ set_res:
|
||||
case SCST_CMD_STATE_PRE_XMIT_RESP:
|
||||
case SCST_CMD_STATE_XMIT_RESP:
|
||||
case SCST_CMD_STATE_FINISHED:
|
||||
case SCST_CMD_STATE_FINISHED_INTERNAL:
|
||||
cmd->state = state;
|
||||
res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
break;
|
||||
@@ -1374,7 +1375,8 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state,
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
if ((next_state != SCST_CMD_STATE_PRE_DEV_DONE) &&
|
||||
(next_state != SCST_CMD_STATE_PRE_XMIT_RESP) &&
|
||||
(next_state != SCST_CMD_STATE_FINISHED)) {
|
||||
(next_state != SCST_CMD_STATE_FINISHED) &&
|
||||
(next_state != SCST_CMD_STATE_FINISHED_INTERNAL)) {
|
||||
PRINT_ERROR("%s() received invalid cmd state %d (opcode %d)",
|
||||
__func__, next_state, cmd->cdb[0]);
|
||||
scst_set_cmd_error(cmd,
|
||||
@@ -2587,10 +2589,9 @@ static void scst_inc_check_expected_sn(struct scst_cmd *cmd)
|
||||
scst_make_deferred_commands_active(cmd->tgt_dev);
|
||||
}
|
||||
|
||||
static int scst_dev_done(struct scst_cmd **pcmd)
|
||||
static int scst_dev_done(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
struct scst_cmd *cmd = *pcmd;
|
||||
int state;
|
||||
struct scst_device *dev = cmd->dev;
|
||||
|
||||
@@ -2638,6 +2639,7 @@ static int scst_dev_done(struct scst_cmd **pcmd)
|
||||
case SCST_CMD_STATE_DEV_DONE:
|
||||
case SCST_CMD_STATE_XMIT_RESP:
|
||||
case SCST_CMD_STATE_FINISHED:
|
||||
case SCST_CMD_STATE_FINISHED_INTERNAL:
|
||||
cmd->state = state;
|
||||
break;
|
||||
|
||||
@@ -2673,8 +2675,8 @@ static int scst_dev_done(struct scst_cmd **pcmd)
|
||||
if (cmd->inc_expected_sn_on_done && cmd->sent_for_exec)
|
||||
scst_inc_check_expected_sn(cmd);
|
||||
|
||||
if (unlikely(cmd->cdb[0] == REQUEST_SENSE) && (cmd->internal))
|
||||
*pcmd = scst_complete_request_sense(cmd);
|
||||
if (unlikely(cmd->internal))
|
||||
cmd->state = SCST_CMD_STATE_FINISHED_INTERNAL;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES(res);
|
||||
@@ -2687,6 +2689,8 @@ static int scst_pre_xmit_response(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
EXTRACHECKS_BUG_ON(cmd->internal);
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG_TM
|
||||
if (cmd->tm_dbg_delayed &&
|
||||
!test_bit(SCST_CMD_ABORTED, &cmd->cmd_flags)) {
|
||||
@@ -2792,6 +2796,8 @@ static int scst_xmit_response(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
EXTRACHECKS_BUG_ON(cmd->internal);
|
||||
|
||||
if (unlikely(!cmd->tgtt->xmit_response_atomic &&
|
||||
scst_cmd_atomic(cmd))) {
|
||||
/*
|
||||
@@ -3402,7 +3408,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
break;
|
||||
|
||||
case SCST_CMD_STATE_DEV_DONE:
|
||||
res = scst_dev_done(&cmd);
|
||||
res = scst_dev_done(cmd);
|
||||
break;
|
||||
|
||||
case SCST_CMD_STATE_PRE_XMIT_RESP:
|
||||
@@ -3421,6 +3427,12 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
SCST_CMD_STATE_RES_NEED_THREAD);
|
||||
break;
|
||||
|
||||
case SCST_CMD_STATE_FINISHED_INTERNAL:
|
||||
res = scst_finish_internal_cmd(cmd);
|
||||
EXTRACHECKS_BUG_ON(res ==
|
||||
SCST_CMD_STATE_RES_NEED_THREAD);
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINT_CRIT_ERROR("cmd (%p) in state %d, but shouldn't "
|
||||
"be", cmd, cmd->state);
|
||||
@@ -3449,6 +3461,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
case SCST_CMD_STATE_PRE_XMIT_RESP:
|
||||
case SCST_CMD_STATE_XMIT_RESP:
|
||||
case SCST_CMD_STATE_FINISHED:
|
||||
case SCST_CMD_STATE_FINISHED_INTERNAL:
|
||||
TRACE_DBG("Adding cmd %p to head of active cmd list",
|
||||
cmd);
|
||||
list_add(&cmd->cmd_list_entry,
|
||||
|
||||
Reference in New Issue
Block a user