mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-20 20:21:30 +00:00
Major cleanups:
- SCST_CMD_STATE_* and SCST_MCMD_STATE_* constants converted to enums and made more readable - Dev handlers don't have to call scst_check_local_events() anymore, except if they implement internal queuing Other minor cleanups and fixes git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@3644 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -160,77 +160,81 @@ static inline unsigned int queue_max_hw_sectors(struct request_queue *q)
|
||||
** more efficient generated code of the corresponding
|
||||
** "switch" statements.
|
||||
*************************************************************/
|
||||
enum {
|
||||
/* Dev handler's parse() is going to be called */
|
||||
SCST_CMD_STATE_PARSE = 0,
|
||||
|
||||
/* Dev handler's parse() is going to be called */
|
||||
#define SCST_CMD_STATE_PARSE 0
|
||||
/* Allocation of the cmd's data buffer */
|
||||
SCST_CMD_STATE_PREPARE_SPACE,
|
||||
|
||||
/* Allocation of the cmd's data buffer */
|
||||
#define SCST_CMD_STATE_PREPARE_SPACE 1
|
||||
/* Calling preprocessing_done() */
|
||||
SCST_CMD_STATE_PREPROCESSING_DONE,
|
||||
|
||||
/* Calling preprocessing_done() */
|
||||
#define SCST_CMD_STATE_PREPROCESSING_DONE 2
|
||||
/* Target driver's rdy_to_xfer() is going to be called */
|
||||
SCST_CMD_STATE_RDY_TO_XFER,
|
||||
|
||||
/* Target driver's rdy_to_xfer() is going to be called */
|
||||
#define SCST_CMD_STATE_RDY_TO_XFER 3
|
||||
/* Target driver's pre_exec() is going to be called */
|
||||
SCST_CMD_STATE_TGT_PRE_EXEC,
|
||||
|
||||
/* Target driver's pre_exec() is going to be called */
|
||||
#define SCST_CMD_STATE_TGT_PRE_EXEC 4
|
||||
/*
|
||||
* Cmd is going to be sent for execution. The first stage of it is
|
||||
* order checking
|
||||
*/
|
||||
SCST_CMD_STATE_EXEC_CHECK_SN,
|
||||
|
||||
/* Cmd is going to be sent for execution */
|
||||
#define SCST_CMD_STATE_SEND_FOR_EXEC 5
|
||||
/* Internal post-exec checks */
|
||||
SCST_CMD_STATE_PRE_DEV_DONE,
|
||||
|
||||
/* Internal post-exec checks */
|
||||
#define SCST_CMD_STATE_PRE_DEV_DONE 6
|
||||
/* Internal MODE SELECT pages related checks */
|
||||
SCST_CMD_STATE_MODE_SELECT_CHECKS,
|
||||
|
||||
/* Internal MODE SELECT pages related checks */
|
||||
#define SCST_CMD_STATE_MODE_SELECT_CHECKS 7
|
||||
/* Dev handler's dev_done() is going to be called */
|
||||
SCST_CMD_STATE_DEV_DONE,
|
||||
|
||||
/* Dev handler's dev_done() is going to be called */
|
||||
#define SCST_CMD_STATE_DEV_DONE 8
|
||||
/* Checks before target driver's xmit_response() is called */
|
||||
SCST_CMD_STATE_PRE_XMIT_RESP,
|
||||
|
||||
/* Checks before target driver's xmit_response() is called */
|
||||
#define SCST_CMD_STATE_PRE_XMIT_RESP 9
|
||||
/* Target driver's xmit_response() is going to be called */
|
||||
SCST_CMD_STATE_XMIT_RESP,
|
||||
|
||||
/* Target driver's xmit_response() is going to be called */
|
||||
#define SCST_CMD_STATE_XMIT_RESP 10
|
||||
/* Cmd finished */
|
||||
SCST_CMD_STATE_FINISHED,
|
||||
|
||||
/* Cmd finished */
|
||||
#define SCST_CMD_STATE_FINISHED 11
|
||||
/* Internal cmd finished */
|
||||
SCST_CMD_STATE_FINISHED_INTERNAL,
|
||||
|
||||
/* Internal cmd finished */
|
||||
#define SCST_CMD_STATE_FINISHED_INTERNAL 12
|
||||
SCST_CMD_STATE_LAST_ACTIVE = (SCST_CMD_STATE_FINISHED_INTERNAL+100),
|
||||
|
||||
#define SCST_CMD_STATE_LAST_ACTIVE (SCST_CMD_STATE_FINISHED_INTERNAL+100)
|
||||
/* A cmd is created, but scst_cmd_init_done() not called */
|
||||
SCST_CMD_STATE_INIT_WAIT,
|
||||
|
||||
/* A cmd is created, but scst_cmd_init_done() not called */
|
||||
#define SCST_CMD_STATE_INIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+1)
|
||||
/* LUN translation (cmd->tgt_dev assignment) */
|
||||
SCST_CMD_STATE_INIT,
|
||||
|
||||
/* LUN translation (cmd->tgt_dev assignment) */
|
||||
#define SCST_CMD_STATE_INIT (SCST_CMD_STATE_LAST_ACTIVE+2)
|
||||
/* Waiting for scst_restart_cmd() */
|
||||
SCST_CMD_STATE_PREPROCESSING_DONE_CALLED,
|
||||
|
||||
/* Waiting for scst_restart_cmd() */
|
||||
#define SCST_CMD_STATE_PREPROCESSING_DONE_CALLED (SCST_CMD_STATE_LAST_ACTIVE+3)
|
||||
/* Waiting for data from the initiator (until scst_rx_data() called) */
|
||||
SCST_CMD_STATE_DATA_WAIT,
|
||||
|
||||
/* Waiting for data from the initiator (until scst_rx_data() called) */
|
||||
#define SCST_CMD_STATE_DATA_WAIT (SCST_CMD_STATE_LAST_ACTIVE+4)
|
||||
/*
|
||||
* Cmd is ready for exec (after check if its device is blocked or should
|
||||
* be blocked)
|
||||
*/
|
||||
SCST_CMD_STATE_EXEC_CHECK_BLOCKING,
|
||||
|
||||
/*
|
||||
* Cmd is ready for exec (after check if its device is blocked or should
|
||||
* be blocked)
|
||||
*/
|
||||
#define SCST_CMD_STATE_START_EXEC (SCST_CMD_STATE_LAST_ACTIVE+5)
|
||||
/* Cmd is being checked if it should be executed locally */
|
||||
SCST_CMD_STATE_LOCAL_EXEC,
|
||||
|
||||
/* Cmd is being checked if it should be executed locally */
|
||||
#define SCST_CMD_STATE_LOCAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+6)
|
||||
/* Cmd is ready for execution */
|
||||
SCST_CMD_STATE_REAL_EXEC,
|
||||
|
||||
/* Cmd is ready for execution */
|
||||
#define SCST_CMD_STATE_REAL_EXEC (SCST_CMD_STATE_LAST_ACTIVE+7)
|
||||
/* Waiting for CDB's execution finish */
|
||||
SCST_CMD_STATE_EXEC_WAIT,
|
||||
|
||||
/* Waiting for CDB's execution finish */
|
||||
#define SCST_CMD_STATE_REAL_EXECUTING (SCST_CMD_STATE_LAST_ACTIVE+8)
|
||||
|
||||
/* Waiting for response's transmission finish */
|
||||
#define SCST_CMD_STATE_XMIT_WAIT (SCST_CMD_STATE_LAST_ACTIVE+9)
|
||||
/* Waiting for response's transmission finish */
|
||||
SCST_CMD_STATE_XMIT_WAIT,
|
||||
};
|
||||
|
||||
/*************************************************************
|
||||
* Can be returned instead of cmd's state by dev handlers'
|
||||
@@ -256,27 +260,28 @@ static inline unsigned int queue_max_hw_sectors(struct request_queue *q)
|
||||
/*************************************************************
|
||||
** States of mgmt command processing state machine
|
||||
*************************************************************/
|
||||
enum {
|
||||
/* LUN translation (mcmd->tgt_dev assignment) */
|
||||
SCST_MCMD_STATE_INIT = 0,
|
||||
|
||||
/* LUN translation (mcmd->tgt_dev assignment) */
|
||||
#define SCST_MCMD_STATE_INIT 0
|
||||
/* Mgmt cmd is being processed */
|
||||
SCST_MCMD_STATE_EXEC,
|
||||
|
||||
/* Mgmt cmd is being processed */
|
||||
#define SCST_MCMD_STATE_EXEC 1
|
||||
/* Waiting for affected commands done */
|
||||
SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_DONE,
|
||||
|
||||
/* Waiting for affected commands done */
|
||||
#define SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_DONE 2
|
||||
/* Post actions when affected commands done */
|
||||
SCST_MCMD_STATE_AFFECTED_CMDS_DONE,
|
||||
|
||||
/* Post actions when affected commands done */
|
||||
#define SCST_MCMD_STATE_AFFECTED_CMDS_DONE 3
|
||||
/* Waiting for affected local commands finished */
|
||||
SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_FINISHED,
|
||||
|
||||
/* Waiting for affected local commands finished */
|
||||
#define SCST_MCMD_STATE_WAITING_AFFECTED_CMDS_FINISHED 4
|
||||
/* Target driver's task_mgmt_fn_done() is going to be called */
|
||||
SCST_MCMD_STATE_DONE,
|
||||
|
||||
/* Target driver's task_mgmt_fn_done() is going to be called */
|
||||
#define SCST_MCMD_STATE_DONE 5
|
||||
|
||||
/* The mcmd finished */
|
||||
#define SCST_MCMD_STATE_FINISHED 6
|
||||
/* The mcmd finished */
|
||||
SCST_MCMD_STATE_FINISHED,
|
||||
};
|
||||
|
||||
/*************************************************************
|
||||
** Constants for "atomic" parameter of SCST's functions
|
||||
@@ -1206,9 +1211,9 @@ struct scst_dev_type {
|
||||
* exec_sync flag and consider to setup dedicated threads by
|
||||
* setting threads_num > 0.
|
||||
*
|
||||
* !! If this function is implemented, scst_check_local_events() !!
|
||||
* !! shall be called inside it just before the actual command's !!
|
||||
* !! execution. !!
|
||||
* Dev handlers implementing internal queuing in their exec() callback
|
||||
* should call scst_check_local_events() just before the actual
|
||||
* command's execution (i.e. after it's taken from the internal queue).
|
||||
*
|
||||
* OPTIONAL, if not set, the commands will be sent directly to SCSI
|
||||
* device.
|
||||
@@ -1895,12 +1900,6 @@ struct scst_cmd {
|
||||
*/
|
||||
unsigned int finished:1;
|
||||
|
||||
/*
|
||||
* Set if scst_check_local_events() can be called more than once. Set by
|
||||
* scst_pre_check_local_events().
|
||||
*/
|
||||
unsigned int check_local_events_once_done:1;
|
||||
|
||||
#ifdef CONFIG_SCST_DEBUG_TM
|
||||
/* Set if the cmd was delayed by task management debugging code */
|
||||
unsigned int tm_dbg_delayed:1;
|
||||
@@ -1920,6 +1919,7 @@ struct scst_cmd {
|
||||
struct scst_tgt_template *tgtt; /* to save extra dereferences */
|
||||
struct scst_tgt *tgt; /* to save extra dereferences */
|
||||
struct scst_device *dev; /* to save extra dereferences */
|
||||
struct scst_dev_type *devt; /* to save extra dereferences */
|
||||
|
||||
/* corresponding I_T_L device for this cmd */
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
@@ -3880,13 +3880,20 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic);
|
||||
void scst_post_parse(struct scst_cmd *cmd);
|
||||
void scst_post_alloc_data_buf(struct scst_cmd *cmd);
|
||||
|
||||
int scst_check_local_events(struct scst_cmd *cmd);
|
||||
int __scst_check_local_events(struct scst_cmd *cmd, bool preempt_tests_only);
|
||||
|
||||
static inline int scst_pre_check_local_events(struct scst_cmd *cmd)
|
||||
/**
|
||||
* scst_check_local_events() - check if there are any local SCSI events
|
||||
*
|
||||
* See description of __scst_check_local_events().
|
||||
*
|
||||
* Dev handlers implementing internal queuing in their exec() callback should
|
||||
* call this function just before the actual command's execution (i.e.
|
||||
* after it's taken from the internal queue).
|
||||
*/
|
||||
static inline int scst_check_local_events(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = scst_check_local_events(cmd);
|
||||
cmd->check_local_events_once_done = 1;
|
||||
return res;
|
||||
return __scst_check_local_events(cmd, true);
|
||||
}
|
||||
|
||||
int scst_set_cmd_abnormal_done_state(struct scst_cmd *cmd);
|
||||
|
||||
@@ -566,10 +566,6 @@ split:
|
||||
if (rc != 0)
|
||||
goto out_error;
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
cmd->status = 0;
|
||||
cmd->msg_status = 0;
|
||||
cmd->host_status = DID_OK;
|
||||
@@ -679,15 +675,11 @@ out_error:
|
||||
|
||||
static int disk_perf_exec(struct scst_cmd *cmd)
|
||||
{
|
||||
int res, rc;
|
||||
int res;
|
||||
int opcode = cmd->cdb[0];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
cmd->status = 0;
|
||||
cmd->msg_status = 0;
|
||||
cmd->host_status = DID_OK;
|
||||
@@ -716,8 +708,6 @@ out:
|
||||
|
||||
out_complete:
|
||||
cmd->completed = 1;
|
||||
|
||||
out_done:
|
||||
res = SCST_EXEC_COMPLETED;
|
||||
cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
|
||||
goto out;
|
||||
|
||||
@@ -335,15 +335,11 @@ static int modisk_done(struct scst_cmd *cmd)
|
||||
|
||||
static int modisk_perf_exec(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_EXEC_NOT_COMPLETED, rc;
|
||||
int res = SCST_EXEC_NOT_COMPLETED;
|
||||
int opcode = cmd->cdb[0];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
cmd->status = 0;
|
||||
cmd->msg_status = 0;
|
||||
cmd->host_status = DID_OK;
|
||||
|
||||
@@ -376,15 +376,11 @@ out:
|
||||
|
||||
static int tape_perf_exec(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_EXEC_NOT_COMPLETED, rc;
|
||||
int res = SCST_EXEC_NOT_COMPLETED;
|
||||
int opcode = cmd->cdb[0];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
cmd->status = 0;
|
||||
cmd->msg_status = 0;
|
||||
cmd->host_status = DID_OK;
|
||||
|
||||
@@ -910,7 +910,7 @@ static void vdisk_detach_tgt(struct scst_tgt_dev *tgt_dev)
|
||||
|
||||
static int vdisk_do_job(struct scst_cmd *cmd)
|
||||
{
|
||||
int rc, res;
|
||||
int res;
|
||||
uint64_t lba_start = 0;
|
||||
loff_t data_len = 0;
|
||||
uint8_t *cdb = cmd->cdb;
|
||||
@@ -936,10 +936,6 @@ static int vdisk_do_job(struct scst_cmd *cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
cmd->status = 0;
|
||||
cmd->msg_status = 0;
|
||||
cmd->host_status = DID_OK;
|
||||
@@ -1167,8 +1163,6 @@ static int vdisk_do_job(struct scst_cmd *cmd)
|
||||
|
||||
out_compl:
|
||||
cmd->completed = 1;
|
||||
|
||||
out_done:
|
||||
cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
|
||||
|
||||
out_thr:
|
||||
|
||||
@@ -1918,11 +1918,11 @@ static int scst_get_cmd_abnormal_done_state(const struct scst_cmd *cmd)
|
||||
case SCST_CMD_STATE_RDY_TO_XFER:
|
||||
case SCST_CMD_STATE_DATA_WAIT:
|
||||
case SCST_CMD_STATE_TGT_PRE_EXEC:
|
||||
case SCST_CMD_STATE_START_EXEC:
|
||||
case SCST_CMD_STATE_SEND_FOR_EXEC:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_BLOCKING:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_SN:
|
||||
case SCST_CMD_STATE_LOCAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXECUTING:
|
||||
case SCST_CMD_STATE_EXEC_WAIT:
|
||||
res = SCST_CMD_STATE_PRE_DEV_DONE;
|
||||
break;
|
||||
|
||||
@@ -1977,11 +1977,11 @@ int scst_set_cmd_abnormal_done_state(struct scst_cmd *cmd)
|
||||
cmd->resid_possible = 1;
|
||||
break;
|
||||
case SCST_CMD_STATE_TGT_PRE_EXEC:
|
||||
case SCST_CMD_STATE_SEND_FOR_EXEC:
|
||||
case SCST_CMD_STATE_START_EXEC:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_SN:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_BLOCKING:
|
||||
case SCST_CMD_STATE_LOCAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXECUTING:
|
||||
case SCST_CMD_STATE_EXEC_WAIT:
|
||||
case SCST_CMD_STATE_DEV_DONE:
|
||||
case SCST_CMD_STATE_PRE_DEV_DONE:
|
||||
case SCST_CMD_STATE_MODE_SELECT_CHECKS:
|
||||
@@ -4275,15 +4275,15 @@ void scst_free_cmd(struct scst_cmd *cmd)
|
||||
}
|
||||
|
||||
if (likely(cmd->dev != NULL)) {
|
||||
struct scst_dev_type *handler = cmd->dev->handler;
|
||||
if (handler->on_free_cmd != NULL) {
|
||||
struct scst_dev_type *devt = cmd->devt;
|
||||
if (devt->on_free_cmd != NULL) {
|
||||
TRACE_DBG("Calling dev handler %s on_free_cmd(%p)",
|
||||
handler->name, cmd);
|
||||
devt->name, cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
handler->on_free_cmd(cmd);
|
||||
devt->on_free_cmd(cmd);
|
||||
scst_set_dev_on_free_time(cmd);
|
||||
TRACE_DBG("Dev handler %s on_free_cmd() returned",
|
||||
handler->name);
|
||||
devt->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4444,10 +4444,10 @@ static bool scst_on_sg_tablesize_low(struct scst_cmd *cmd, bool out)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (tgt_dev->dev->handler->on_sg_tablesize_low == NULL)
|
||||
if (cmd->devt->on_sg_tablesize_low == NULL)
|
||||
goto failed;
|
||||
|
||||
res = tgt_dev->dev->handler->on_sg_tablesize_low(cmd);
|
||||
res = cmd->devt->on_sg_tablesize_low(cmd);
|
||||
|
||||
TRACE_DBG("on_sg_tablesize_low(%p) returned %d", cmd, res);
|
||||
|
||||
@@ -5891,151 +5891,6 @@ enum dma_data_direction scst_to_tgt_dma_dir(int scst_dir)
|
||||
}
|
||||
EXPORT_SYMBOL(scst_to_tgt_dma_dir);
|
||||
|
||||
/**
|
||||
* scst_obtain_device_parameters() - obtain device control parameters
|
||||
*
|
||||
* Issues a MODE SENSE for control mode page data and sets the corresponding
|
||||
* dev's parameter from it. Returns 0 on success and not 0 otherwise.
|
||||
*/
|
||||
int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
{
|
||||
int rc, i;
|
||||
uint8_t cmd[16];
|
||||
uint8_t buffer[4+0x0A];
|
||||
uint8_t sense_buffer[SCSI_SENSE_BUFFERSIZE];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
EXTRACHECKS_BUG_ON(dev->scsi_dev == NULL);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
/* Get control mode page */
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
#if 0
|
||||
cmd[0] = MODE_SENSE_10;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0x0A;
|
||||
cmd[8] = sizeof(buffer); /* it's < 256 */
|
||||
#else
|
||||
cmd[0] = MODE_SENSE;
|
||||
cmd[1] = 8; /* DBD */
|
||||
cmd[2] = 0x0A;
|
||||
cmd[4] = sizeof(buffer);
|
||||
#endif
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(sense_buffer, 0, sizeof(sense_buffer));
|
||||
|
||||
TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE");
|
||||
rc = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer,
|
||||
sizeof(buffer), sense_buffer, 15, 0, 0
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
|
||||
, NULL
|
||||
#endif
|
||||
);
|
||||
|
||||
TRACE_DBG("MODE_SENSE done: %x", rc);
|
||||
|
||||
if (scsi_status_is_good(rc)) {
|
||||
int q;
|
||||
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI, "Returned control mode "
|
||||
"page data", buffer, sizeof(buffer));
|
||||
|
||||
dev->tst = buffer[4+2] >> 5;
|
||||
q = buffer[4+3] >> 4;
|
||||
if (q > SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER) {
|
||||
PRINT_ERROR("Too big QUEUE ALG %x, dev %s",
|
||||
dev->queue_alg, dev->virt_name);
|
||||
}
|
||||
dev->queue_alg = q;
|
||||
dev->swp = (buffer[4+4] & 0x8) >> 3;
|
||||
dev->tas = (buffer[4+5] & 0x40) >> 6;
|
||||
dev->d_sense = (buffer[4+2] & 0x4) >> 2;
|
||||
|
||||
/*
|
||||
* Unfortunately, SCSI ML doesn't provide a way to
|
||||
* specify commands task attribute, so we can rely on
|
||||
* device's restricted reordering only. Linux I/O
|
||||
* subsystem doesn't reorder pass-through (PC) requests.
|
||||
*/
|
||||
dev->has_own_order_mgmt = !dev->queue_alg;
|
||||
|
||||
PRINT_INFO("Device %s: TST %x, QUEUE ALG %x, SWP %x, "
|
||||
"TAS %x, D_SENSE %d, has_own_order_mgmt %d",
|
||||
dev->virt_name, dev->tst, dev->queue_alg,
|
||||
dev->swp, dev->tas, dev->d_sense,
|
||||
dev->has_own_order_mgmt);
|
||||
|
||||
goto out;
|
||||
} else {
|
||||
scst_check_internal_sense(dev, rc, sense_buffer,
|
||||
sizeof(sense_buffer));
|
||||
#if 0
|
||||
if ((status_byte(rc) == CHECK_CONDITION) &&
|
||||
SCST_SENSE_VALID(sense_buffer)) {
|
||||
#else
|
||||
/*
|
||||
* 3ware controller is buggy and returns CONDITION_GOOD
|
||||
* instead of CHECK_CONDITION
|
||||
*/
|
||||
if (SCST_SENSE_VALID(sense_buffer)) {
|
||||
#endif
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI, "Returned sense "
|
||||
"data", sense_buffer,
|
||||
sizeof(sense_buffer));
|
||||
if (scst_analyze_sense(sense_buffer,
|
||||
sizeof(sense_buffer),
|
||||
SCST_SENSE_KEY_VALID,
|
||||
ILLEGAL_REQUEST, 0, 0)) {
|
||||
PRINT_INFO("Device %s doesn't support "
|
||||
"MODE SENSE", dev->virt_name);
|
||||
break;
|
||||
} else if (scst_analyze_sense(sense_buffer,
|
||||
sizeof(sense_buffer),
|
||||
SCST_SENSE_KEY_VALID,
|
||||
NOT_READY, 0, 0)) {
|
||||
PRINT_ERROR("Device %s not ready",
|
||||
dev->virt_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
PRINT_INFO("Internal MODE SENSE to "
|
||||
"device %s failed: %x",
|
||||
dev->virt_name, rc);
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI, "MODE SENSE sense",
|
||||
sense_buffer, sizeof(sense_buffer));
|
||||
switch (host_byte(rc)) {
|
||||
case DID_RESET:
|
||||
case DID_ABORT:
|
||||
case DID_SOFT_ERROR:
|
||||
break;
|
||||
default:
|
||||
goto brk;
|
||||
}
|
||||
switch (driver_byte(rc)) {
|
||||
case DRIVER_BUSY:
|
||||
case DRIVER_SOFT:
|
||||
break;
|
||||
default:
|
||||
goto brk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
brk:
|
||||
PRINT_WARNING("Unable to get device's %s control mode page, using "
|
||||
"existing values/defaults: TST %x, QUEUE ALG %x, SWP %x, "
|
||||
"TAS %x, D_SENSE %d, has_own_order_mgmt %d", dev->virt_name,
|
||||
dev->tst, dev->queue_alg, dev->swp, dev->tas, dev->d_sense,
|
||||
dev->has_own_order_mgmt);
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scst_obtain_device_parameters);
|
||||
|
||||
/* Called under dev_lock and BH off */
|
||||
void scst_process_reset(struct scst_device *dev,
|
||||
struct scst_session *originator, struct scst_cmd *exclude_cmd,
|
||||
@@ -6775,6 +6630,151 @@ void scst_unblock_dev(struct scst_device *dev)
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* scst_obtain_device_parameters() - obtain device control parameters
|
||||
*
|
||||
* Issues a MODE SENSE for control mode page data and sets the corresponding
|
||||
* dev's parameter from it. Returns 0 on success and not 0 otherwise.
|
||||
*/
|
||||
int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
{
|
||||
int rc, i;
|
||||
uint8_t cmd[16];
|
||||
uint8_t buffer[4+0x0A];
|
||||
uint8_t sense_buffer[SCSI_SENSE_BUFFERSIZE];
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
EXTRACHECKS_BUG_ON(dev->scsi_dev == NULL);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
/* Get control mode page */
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
#if 0
|
||||
cmd[0] = MODE_SENSE_10;
|
||||
cmd[1] = 0;
|
||||
cmd[2] = 0x0A;
|
||||
cmd[8] = sizeof(buffer); /* it's < 256 */
|
||||
#else
|
||||
cmd[0] = MODE_SENSE;
|
||||
cmd[1] = 8; /* DBD */
|
||||
cmd[2] = 0x0A;
|
||||
cmd[4] = sizeof(buffer);
|
||||
#endif
|
||||
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memset(sense_buffer, 0, sizeof(sense_buffer));
|
||||
|
||||
TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE");
|
||||
rc = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer,
|
||||
sizeof(buffer), sense_buffer, 15, 0, 0
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
|
||||
, NULL
|
||||
#endif
|
||||
);
|
||||
|
||||
TRACE_DBG("MODE_SENSE done: %x", rc);
|
||||
|
||||
if (scsi_status_is_good(rc)) {
|
||||
int q;
|
||||
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI, "Returned control mode "
|
||||
"page data", buffer, sizeof(buffer));
|
||||
|
||||
dev->tst = buffer[4+2] >> 5;
|
||||
q = buffer[4+3] >> 4;
|
||||
if (q > SCST_CONTR_MODE_QUEUE_ALG_UNRESTRICTED_REORDER) {
|
||||
PRINT_ERROR("Too big QUEUE ALG %x, dev %s",
|
||||
dev->queue_alg, dev->virt_name);
|
||||
}
|
||||
dev->queue_alg = q;
|
||||
dev->swp = (buffer[4+4] & 0x8) >> 3;
|
||||
dev->tas = (buffer[4+5] & 0x40) >> 6;
|
||||
dev->d_sense = (buffer[4+2] & 0x4) >> 2;
|
||||
|
||||
/*
|
||||
* Unfortunately, SCSI ML doesn't provide a way to
|
||||
* specify commands task attribute, so we can rely on
|
||||
* device's restricted reordering only. Linux I/O
|
||||
* subsystem doesn't reorder pass-through (PC) requests.
|
||||
*/
|
||||
dev->has_own_order_mgmt = !dev->queue_alg;
|
||||
|
||||
PRINT_INFO("Device %s: TST %x, QUEUE ALG %x, SWP %x, "
|
||||
"TAS %x, D_SENSE %d, has_own_order_mgmt %d",
|
||||
dev->virt_name, dev->tst, dev->queue_alg,
|
||||
dev->swp, dev->tas, dev->d_sense,
|
||||
dev->has_own_order_mgmt);
|
||||
|
||||
goto out;
|
||||
} else {
|
||||
scst_check_internal_sense(dev, rc, sense_buffer,
|
||||
sizeof(sense_buffer));
|
||||
#if 0
|
||||
if ((status_byte(rc) == CHECK_CONDITION) &&
|
||||
SCST_SENSE_VALID(sense_buffer)) {
|
||||
#else
|
||||
/*
|
||||
* 3ware controller is buggy and returns CONDITION_GOOD
|
||||
* instead of CHECK_CONDITION
|
||||
*/
|
||||
if (SCST_SENSE_VALID(sense_buffer)) {
|
||||
#endif
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI, "Returned sense "
|
||||
"data", sense_buffer,
|
||||
sizeof(sense_buffer));
|
||||
if (scst_analyze_sense(sense_buffer,
|
||||
sizeof(sense_buffer),
|
||||
SCST_SENSE_KEY_VALID,
|
||||
ILLEGAL_REQUEST, 0, 0)) {
|
||||
PRINT_INFO("Device %s doesn't support "
|
||||
"MODE SENSE", dev->virt_name);
|
||||
break;
|
||||
} else if (scst_analyze_sense(sense_buffer,
|
||||
sizeof(sense_buffer),
|
||||
SCST_SENSE_KEY_VALID,
|
||||
NOT_READY, 0, 0)) {
|
||||
PRINT_ERROR("Device %s not ready",
|
||||
dev->virt_name);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
PRINT_INFO("Internal MODE SENSE to "
|
||||
"device %s failed: %x",
|
||||
dev->virt_name, rc);
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI, "MODE SENSE sense",
|
||||
sense_buffer, sizeof(sense_buffer));
|
||||
switch (host_byte(rc)) {
|
||||
case DID_RESET:
|
||||
case DID_ABORT:
|
||||
case DID_SOFT_ERROR:
|
||||
break;
|
||||
default:
|
||||
goto brk;
|
||||
}
|
||||
switch (driver_byte(rc)) {
|
||||
case DRIVER_BUSY:
|
||||
case DRIVER_SOFT:
|
||||
break;
|
||||
default:
|
||||
goto brk;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
brk:
|
||||
PRINT_WARNING("Unable to get device's %s control mode page, using "
|
||||
"existing values/defaults: TST %x, QUEUE ALG %x, SWP %x, "
|
||||
"TAS %x, D_SENSE %d, has_own_order_mgmt %d", dev->virt_name,
|
||||
dev->tst, dev->queue_alg, dev->swp, dev->tas, dev->d_sense,
|
||||
dev->has_own_order_mgmt);
|
||||
|
||||
out:
|
||||
TRACE_EXIT();
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scst_obtain_device_parameters);
|
||||
|
||||
void scst_on_hq_cmd_response(struct scst_cmd *cmd)
|
||||
{
|
||||
struct scst_order_data *order_data = cmd->cur_order_data;
|
||||
|
||||
@@ -73,10 +73,9 @@ static inline void scst_dec_pr_readers_count(struct scst_cmd *cmd,
|
||||
struct scst_device *dev = cmd->dev;
|
||||
|
||||
if (unlikely(!cmd->dec_pr_readers_count_needed)) {
|
||||
PRINT_ERROR("scst_check_local_events() should not be called "
|
||||
"twice (cmd %p, op %x)! Use "
|
||||
"scst_pre_check_local_events() instead.", cmd,
|
||||
cmd->cdb[0]);
|
||||
PRINT_ERROR("__scst_check_local_events(x, false) should not "
|
||||
"be called twice (cmd %p, op %x)! Use "
|
||||
"scst_check_local_events() instead.", cmd, cmd->cdb[0]);
|
||||
WARN_ON(1);
|
||||
goto out;
|
||||
}
|
||||
@@ -99,14 +98,6 @@ out:
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void scst_reset_requeued_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
TRACE_DBG("Reset requeued cmd %p (op %x)", cmd, cmd->cdb[0]);
|
||||
scst_inc_pr_readers_count(cmd, false);
|
||||
cmd->check_local_events_once_done = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static inline bool scst_pr_type_valid(uint8_t type)
|
||||
{
|
||||
switch (type) {
|
||||
|
||||
@@ -466,6 +466,7 @@ int scst_pre_parse(struct scst_cmd *cmd)
|
||||
{
|
||||
int res;
|
||||
struct scst_device *dev = cmd->dev;
|
||||
struct scst_dev_type *devt = cmd->devt;
|
||||
int rc;
|
||||
|
||||
TRACE_ENTRY();
|
||||
@@ -488,7 +489,7 @@ int scst_pre_parse(struct scst_cmd *cmd)
|
||||
|
||||
TRACE(TRACE_MINOR, "Unknown opcode 0x%02x for %s. "
|
||||
"Should you update scst_scsi_op_table?",
|
||||
cmd->cdb[0], dev->handler->name);
|
||||
cmd->cdb[0], devt->name);
|
||||
PRINT_BUFF_FLAG(TRACE_MINOR, "Failed CDB", cmd->cdb,
|
||||
cmd->cdb_len);
|
||||
} else
|
||||
@@ -497,7 +498,7 @@ int scst_pre_parse(struct scst_cmd *cmd)
|
||||
#ifdef CONFIG_SCST_STRICT_SERIALIZING
|
||||
cmd->inc_expected_sn_on_done = 1;
|
||||
#else
|
||||
cmd->inc_expected_sn_on_done = dev->handler->exec_sync ||
|
||||
cmd->inc_expected_sn_on_done = devt->exec_sync ||
|
||||
(!dev->has_own_order_mgmt &&
|
||||
(dev->queue_alg == SCST_CONTR_MODE_QUEUE_ALG_RESTRICTED_REORDER ||
|
||||
cmd->queue_type == SCST_CMD_QUEUE_ORDERED));
|
||||
@@ -555,45 +556,45 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
int state;
|
||||
struct scst_device *dev = cmd->dev;
|
||||
struct scst_dev_type *devt = cmd->devt;
|
||||
int orig_bufflen = cmd->bufflen;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
if (likely(!scst_is_cmd_fully_local(cmd))) {
|
||||
if (unlikely(!dev->handler->parse_atomic &&
|
||||
if (unlikely(!devt->parse_atomic &&
|
||||
scst_cmd_atomic(cmd))) {
|
||||
/*
|
||||
* It shouldn't be because of the SCST_TGT_DEV_AFTER_*
|
||||
* optimization.
|
||||
*/
|
||||
TRACE_MGMT_DBG("Dev handler %s parse() needs thread "
|
||||
"context, rescheduling", dev->handler->name);
|
||||
"context, rescheduling", devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
TRACE_DBG("Calling dev handler %s parse(%p)",
|
||||
dev->handler->name, cmd);
|
||||
devt->name, cmd);
|
||||
TRACE_BUFF_FLAG(TRACE_SND_BOT, "Parsing: ",
|
||||
cmd->cdb, cmd->cdb_len);
|
||||
scst_set_cur_start(cmd);
|
||||
state = dev->handler->parse(cmd);
|
||||
state = devt->parse(cmd);
|
||||
/* Caution: cmd can be already dead here */
|
||||
TRACE_DBG("Dev handler %s parse() returned %d",
|
||||
dev->handler->name, state);
|
||||
devt->name, state);
|
||||
|
||||
switch (state) {
|
||||
case SCST_CMD_STATE_NEED_THREAD_CTX:
|
||||
scst_set_parse_time(cmd);
|
||||
TRACE_DBG("Dev handler %s parse() requested thread "
|
||||
"context, rescheduling", dev->handler->name);
|
||||
"context, rescheduling", devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
goto out;
|
||||
|
||||
case SCST_CMD_STATE_STOP:
|
||||
TRACE_DBG("Dev handler %s parse() requested stop "
|
||||
"processing", dev->handler->name);
|
||||
"processing", devt->name);
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
goto out;
|
||||
}
|
||||
@@ -622,7 +623,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
} else {
|
||||
PRINT_ERROR("Unknown opcode 0x%02x for %s and "
|
||||
"target %s not supplied expected values",
|
||||
cmd->cdb[0], dev->handler->name, cmd->tgtt->name);
|
||||
cmd->cdb[0], devt->name, cmd->tgtt->name);
|
||||
scst_set_cmd_error(cmd,
|
||||
SCST_LOAD_SENSE(scst_sense_invalid_opcode));
|
||||
goto out_done;
|
||||
@@ -683,7 +684,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
} else {
|
||||
PRINT_ERROR("Unknown data transfer length for opcode "
|
||||
"0x%x (handler %s, target %s)", cmd->cdb[0],
|
||||
dev->handler->name, cmd->tgtt->name);
|
||||
devt->name, cmd->tgtt->name);
|
||||
PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
|
||||
scst_set_cmd_error(cmd,
|
||||
SCST_LOAD_SENSE(scst_sense_invalid_message));
|
||||
@@ -722,7 +723,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
((cmd->sg == NULL) && (state > SCST_CMD_STATE_PREPARE_SPACE)))) {
|
||||
PRINT_ERROR("Dev handler %s parse() returned "
|
||||
"invalid cmd data_direction %d, bufflen %d, state %d "
|
||||
"or sg %p (opcode 0x%x)", dev->handler->name,
|
||||
"or sg %p (opcode 0x%x)", devt->name,
|
||||
cmd->data_direction, cmd->bufflen, state, cmd->sg,
|
||||
cmd->cdb[0]);
|
||||
PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
|
||||
@@ -761,7 +762,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
"opcode 0x%02x (handler %s, target %s) "
|
||||
"doesn't match decoded value %d",
|
||||
cmd->expected_data_direction,
|
||||
cmd->cdb[0], dev->handler->name,
|
||||
cmd->cdb[0], devt->name,
|
||||
cmd->tgtt->name, cmd->data_direction);
|
||||
PRINT_BUFFER("Failed CDB", cmd->cdb,
|
||||
cmd->cdb_len);
|
||||
@@ -776,8 +777,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
"(handler %s, target %s) doesn't match "
|
||||
"decoded value %d",
|
||||
cmd->expected_transfer_len, cmd->cdb[0],
|
||||
dev->handler->name, cmd->tgtt->name,
|
||||
cmd->bufflen);
|
||||
devt->name, cmd->tgtt->name, cmd->bufflen);
|
||||
PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB",
|
||||
cmd->cdb, cmd->cdb_len);
|
||||
if ((cmd->data_direction & SCST_DATA_READ) ||
|
||||
@@ -790,7 +790,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
"(handler %s, target %s) doesn't match "
|
||||
"decoded value %d",
|
||||
cmd->expected_out_transfer_len, cmd->cdb[0],
|
||||
dev->handler->name, cmd->tgtt->name,
|
||||
devt->name, cmd->tgtt->name,
|
||||
cmd->out_bufflen);
|
||||
PRINT_BUFF_FLAG(TRACE_MINOR, "Suspicious CDB",
|
||||
cmd->cdb, cmd->cdb_len);
|
||||
@@ -801,7 +801,7 @@ static int scst_parse_cmd(struct scst_cmd *cmd)
|
||||
|
||||
if (unlikely(cmd->data_direction == SCST_DATA_UNKNOWN)) {
|
||||
PRINT_ERROR("Unknown data direction. Opcode 0x%x, handler %s, "
|
||||
"target %s", cmd->cdb[0], dev->handler->name,
|
||||
"target %s", cmd->cdb[0], devt->name,
|
||||
cmd->tgtt->name);
|
||||
PRINT_BUFFER("Failed CDB", cmd->cdb, cmd->cdb_len);
|
||||
goto out_hw_error;
|
||||
@@ -825,8 +825,8 @@ set_res:
|
||||
case SCST_CMD_STATE_PARSE:
|
||||
case SCST_CMD_STATE_RDY_TO_XFER:
|
||||
case SCST_CMD_STATE_TGT_PRE_EXEC:
|
||||
case SCST_CMD_STATE_SEND_FOR_EXEC:
|
||||
case SCST_CMD_STATE_START_EXEC:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_SN:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_BLOCKING:
|
||||
case SCST_CMD_STATE_LOCAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXEC:
|
||||
case SCST_CMD_STATE_PRE_DEV_DONE:
|
||||
@@ -845,10 +845,10 @@ set_res:
|
||||
if (state >= 0) {
|
||||
PRINT_ERROR("Dev handler %s parse() returned "
|
||||
"invalid cmd state %d (opcode %d)",
|
||||
dev->handler->name, state, cmd->cdb[0]);
|
||||
devt->name, state, cmd->cdb[0]);
|
||||
} else {
|
||||
PRINT_ERROR("Dev handler %s parse() returned "
|
||||
"error %d (opcode %d)", dev->handler->name,
|
||||
"error %d (opcode %d)", devt->name,
|
||||
state, cmd->cdb[0]);
|
||||
}
|
||||
goto out_hw_error;
|
||||
@@ -937,7 +937,7 @@ out:
|
||||
static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
{
|
||||
int r = 0, res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
struct scst_device *dev = cmd->dev;
|
||||
struct scst_dev_type *devt = cmd->devt;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
@@ -945,10 +945,10 @@ static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
goto done;
|
||||
|
||||
if (likely(!scst_is_cmd_fully_local(cmd)) &&
|
||||
(dev->handler->alloc_data_buf != NULL)) {
|
||||
(devt->alloc_data_buf != NULL)) {
|
||||
int state;
|
||||
|
||||
if (unlikely(!dev->handler->alloc_data_buf_atomic &&
|
||||
if (unlikely(!devt->alloc_data_buf_atomic &&
|
||||
scst_cmd_atomic(cmd))) {
|
||||
/*
|
||||
* It shouldn't be because of the SCST_TGT_DEV_AFTER_*
|
||||
@@ -956,31 +956,35 @@ static int scst_prepare_space(struct scst_cmd *cmd)
|
||||
*/
|
||||
TRACE_MGMT_DBG("Dev handler %s alloc_data_buf() needs "
|
||||
"thread context, rescheduling",
|
||||
dev->handler->name);
|
||||
devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
TRACE_DBG("Calling dev handler %s alloc_data_buf(%p)",
|
||||
dev->handler->name, cmd);
|
||||
TRACE_DBG("Calling dev handler %s (%p) alloc_data_buf(%p)",
|
||||
devt->name, devt, cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
state = dev->handler->alloc_data_buf(cmd);
|
||||
/* Caution: cmd can be already dead here */
|
||||
TRACE_DBG("Dev handler %s alloc_data_buf() returned %d",
|
||||
dev->handler->name, state);
|
||||
state = devt->alloc_data_buf(cmd);
|
||||
/*
|
||||
* Caution: cmd can be already dead here
|
||||
*/
|
||||
|
||||
/* cmd can be already dead here, so we can't dereference devt */
|
||||
TRACE_DBG("Dev handler %p alloc_data_buf() returned %d",
|
||||
devt, state);
|
||||
|
||||
switch (state) {
|
||||
case SCST_CMD_STATE_NEED_THREAD_CTX:
|
||||
scst_set_alloc_buf_time(cmd);
|
||||
TRACE_DBG("Dev handler %s alloc_data_buf() requested "
|
||||
"thread context, rescheduling",
|
||||
dev->handler->name);
|
||||
"thread context, rescheduling", devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
goto out;
|
||||
|
||||
case SCST_CMD_STATE_STOP:
|
||||
TRACE_DBG("Dev handler %s alloc_data_buf() requested "
|
||||
"stop processing", dev->handler->name);
|
||||
/* cmd can be already dead here, so we can't deref devt */
|
||||
TRACE_DBG("Dev handler %p alloc_data_buf() requested "
|
||||
"stop processing", devt);
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
goto out;
|
||||
}
|
||||
@@ -1507,7 +1511,7 @@ static int scst_tgt_pre_exec(struct scst_cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
cmd->state = SCST_CMD_STATE_SEND_FOR_EXEC;
|
||||
cmd->state = SCST_CMD_STATE_EXEC_CHECK_SN;
|
||||
|
||||
if ((cmd->tgtt->pre_exec == NULL) || unlikely(cmd->internal))
|
||||
goto out;
|
||||
@@ -1686,7 +1690,7 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state,
|
||||
|
||||
static int scst_report_luns_local(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_EXEC_COMPLETED, rc;
|
||||
int res = SCST_EXEC_COMPLETED;
|
||||
int dev_cnt = 0;
|
||||
int buffer_size;
|
||||
int i;
|
||||
@@ -1696,10 +1700,6 @@ static int scst_report_luns_local(struct scst_cmd *cmd)
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
cmd->status = 0;
|
||||
cmd->msg_status = 0;
|
||||
cmd->host_status = DID_OK;
|
||||
@@ -1791,7 +1791,6 @@ out_compl:
|
||||
}
|
||||
}
|
||||
|
||||
out_done:
|
||||
/* Report the result */
|
||||
cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
|
||||
|
||||
@@ -1813,17 +1812,13 @@ out_hw_err:
|
||||
|
||||
static int scst_request_sense_local(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_EXEC_COMPLETED, rc;
|
||||
int res = SCST_EXEC_COMPLETED;
|
||||
struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
|
||||
uint8_t *buffer;
|
||||
int buffer_size = 0, sl = 0;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
cmd->status = 0;
|
||||
cmd->msg_status = 0;
|
||||
cmd->host_status = DID_OK;
|
||||
@@ -1891,7 +1886,6 @@ static int scst_request_sense_local(struct scst_cmd *cmd)
|
||||
out_compl:
|
||||
cmd->completed = 1;
|
||||
|
||||
out_done:
|
||||
/* Report the result */
|
||||
cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
|
||||
|
||||
@@ -1916,7 +1910,7 @@ out_unlock_compl:
|
||||
|
||||
static int scst_reserve_local(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_EXEC_NOT_COMPLETED, rc;
|
||||
int res = SCST_EXEC_NOT_COMPLETED;
|
||||
struct scst_device *dev;
|
||||
struct scst_tgt_dev *tgt_dev_tmp;
|
||||
|
||||
@@ -1949,10 +1943,6 @@ static int scst_reserve_local(struct scst_cmd *cmd)
|
||||
* it, also there's no point to do any extra protection actions.
|
||||
*/
|
||||
|
||||
rc = scst_pre_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
if (!list_empty(&dev->dev_registrants_list)) {
|
||||
if (scst_pr_crh_case(cmd))
|
||||
goto out_completed;
|
||||
@@ -1997,7 +1987,7 @@ out_done:
|
||||
|
||||
static int scst_release_local(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_EXEC_NOT_COMPLETED, rc;
|
||||
int res = SCST_EXEC_NOT_COMPLETED;
|
||||
struct scst_tgt_dev *tgt_dev_tmp;
|
||||
struct scst_device *dev;
|
||||
|
||||
@@ -2010,10 +2000,6 @@ static int scst_release_local(struct scst_cmd *cmd)
|
||||
* other protection is needed here.
|
||||
*/
|
||||
|
||||
rc = scst_pre_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
if (!list_empty(&dev->dev_registrants_list)) {
|
||||
if (scst_pr_crh_case(cmd))
|
||||
goto out_completed;
|
||||
@@ -2070,7 +2056,6 @@ out_done:
|
||||
/* No locks, no IRQ or IRQ-disabled context allowed */
|
||||
static int scst_persistent_reserve_in_local(struct scst_cmd *cmd)
|
||||
{
|
||||
int rc;
|
||||
struct scst_device *dev;
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
struct scst_session *session;
|
||||
@@ -2086,10 +2071,6 @@ static int scst_persistent_reserve_in_local(struct scst_cmd *cmd)
|
||||
tgt_dev = cmd->tgt_dev;
|
||||
session = cmd->sess;
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
if (unlikely(dev->not_pr_supporting_tgt_devs_num != 0)) {
|
||||
PRINT_WARNING("Persistent Reservation command %x refused for "
|
||||
"device %s, because the device has not supporting PR "
|
||||
@@ -2177,7 +2158,6 @@ out_err:
|
||||
static int scst_persistent_reserve_out_local(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_EXEC_COMPLETED;
|
||||
int rc;
|
||||
struct scst_device *dev;
|
||||
struct scst_tgt_dev *tgt_dev;
|
||||
struct scst_session *session;
|
||||
@@ -2194,10 +2174,6 @@ static int scst_persistent_reserve_out_local(struct scst_cmd *cmd)
|
||||
tgt_dev = cmd->tgt_dev;
|
||||
session = cmd->sess;
|
||||
|
||||
rc = scst_check_local_events(cmd);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
if (unlikely(dev->not_pr_supporting_tgt_devs_num != 0)) {
|
||||
PRINT_WARNING("Persistent Reservation command %x refused for "
|
||||
"device %s, because the device has not supporting PR "
|
||||
@@ -2312,7 +2288,7 @@ static int scst_persistent_reserve_out_local(struct scst_cmd *cmd)
|
||||
scst_pr_sync_device_file(tgt_dev, cmd);
|
||||
#endif
|
||||
|
||||
if ((dev->handler->pr_cmds_notifications) &&
|
||||
if ((cmd->devt->pr_cmds_notifications) &&
|
||||
(cmd->status == SAM_STAT_GOOD)) /* sync file may change status */
|
||||
res = SCST_EXEC_NOT_COMPLETED;
|
||||
|
||||
@@ -2335,7 +2311,7 @@ out_done:
|
||||
}
|
||||
|
||||
/**
|
||||
* scst_check_local_events() - check if there are any local SCSI events
|
||||
* __scst_check_local_events() - check if there are any local SCSI events
|
||||
*
|
||||
* Description:
|
||||
* Checks if the command can be executed or there are local events,
|
||||
@@ -2343,15 +2319,9 @@ out_done:
|
||||
* aborted, > 0 if there is an event and command should be immediately
|
||||
* completed, or 0 otherwise.
|
||||
*
|
||||
* !! 1.Dev handlers implementing exec() callback must call this function there
|
||||
* !! just before the actual command's execution!
|
||||
* !!
|
||||
* !! 2. If this function can be called more than once on the processing path
|
||||
* !! scst_pre_check_local_events() should be used for the first call!
|
||||
*
|
||||
* On call no locks, no IRQ or IRQ-disabled context allowed.
|
||||
*/
|
||||
int scst_check_local_events(struct scst_cmd *cmd)
|
||||
int __scst_check_local_events(struct scst_cmd *cmd, bool preempt_tests_only)
|
||||
{
|
||||
int res, rc;
|
||||
struct scst_tgt_dev *tgt_dev = cmd->tgt_dev;
|
||||
@@ -2376,7 +2346,7 @@ int scst_check_local_events(struct scst_cmd *cmd)
|
||||
}
|
||||
}
|
||||
|
||||
if (likely(!cmd->check_local_events_once_done)) {
|
||||
if (!preempt_tests_only) {
|
||||
if (dev->pr_is_set) {
|
||||
if (unlikely(!scst_pr_is_cmd_allowed(cmd))) {
|
||||
scst_set_cmd_error_status(cmd,
|
||||
@@ -2451,7 +2421,7 @@ out_uncomplete:
|
||||
res = -1;
|
||||
goto out;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(scst_check_local_events);
|
||||
EXPORT_SYMBOL_GPL(__scst_check_local_events);
|
||||
|
||||
/* No locks */
|
||||
void scst_inc_expected_sn(struct scst_order_data *order_data, atomic_t *slot)
|
||||
@@ -2493,7 +2463,7 @@ inc:
|
||||
order_data->expected_sn++;
|
||||
/*
|
||||
* Write must be before def_cmd_count read to be in sync. with
|
||||
* scst_post_exec_sn(). See comment in scst_send_for_exec().
|
||||
* scst_post_exec_sn(). See comment in scst_exec_check_sn().
|
||||
*/
|
||||
smp_mb();
|
||||
TRACE_SN("Next expected_sn: %d", order_data->expected_sn);
|
||||
@@ -2533,7 +2503,7 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
int res = SCST_EXEC_NOT_COMPLETED;
|
||||
int rc;
|
||||
struct scst_device *dev = cmd->dev;
|
||||
struct scst_dev_type *handler = dev->handler;
|
||||
struct scst_dev_type *devt = cmd->devt;
|
||||
struct io_context *old_ctx = NULL;
|
||||
bool ctx_changed = false;
|
||||
struct scsi_device *scsi_dev;
|
||||
@@ -2542,17 +2512,17 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
|
||||
ctx_changed = scst_set_io_context(cmd, &old_ctx);
|
||||
|
||||
cmd->state = SCST_CMD_STATE_REAL_EXECUTING;
|
||||
cmd->state = SCST_CMD_STATE_EXEC_WAIT;
|
||||
|
||||
if (handler->exec) {
|
||||
if (devt->exec) {
|
||||
TRACE_DBG("Calling dev handler %s exec(%p)",
|
||||
handler->name, cmd);
|
||||
devt->name, cmd);
|
||||
TRACE_BUFF_FLAG(TRACE_SND_TOP, "Execing: ", cmd->cdb,
|
||||
cmd->cdb_len);
|
||||
scst_set_cur_start(cmd);
|
||||
res = handler->exec(cmd);
|
||||
res = devt->exec(cmd);
|
||||
TRACE_DBG("Dev handler %s exec() returned %d",
|
||||
handler->name, res);
|
||||
devt->name, res);
|
||||
|
||||
if (res == SCST_EXEC_COMPLETED)
|
||||
goto out_complete;
|
||||
@@ -2573,10 +2543,6 @@ static int scst_do_real_exec(struct scst_cmd *cmd)
|
||||
goto out_error;
|
||||
}
|
||||
|
||||
res = scst_check_local_events(cmd);
|
||||
if (unlikely(res != 0))
|
||||
goto out_done;
|
||||
|
||||
scst_set_cur_start(cmd);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
|
||||
@@ -2736,15 +2702,37 @@ static int scst_local_exec(struct scst_cmd *cmd)
|
||||
return res;
|
||||
}
|
||||
|
||||
static int scst_exec(struct scst_cmd **active_cmd)
|
||||
static int scst_pre_exec_checks(struct scst_cmd *cmd)
|
||||
{
|
||||
struct scst_cmd *cmd = *active_cmd;
|
||||
struct scst_cmd *ref_cmd;
|
||||
int res = SCST_CMD_STATE_RES_CONT_NEXT, count = 0;
|
||||
int res, rc;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
cmd->state = SCST_CMD_STATE_START_EXEC;
|
||||
rc = __scst_check_local_events(cmd, false);
|
||||
if (unlikely(rc != 0))
|
||||
goto out_done;
|
||||
|
||||
res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
|
||||
out:
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
|
||||
out_done:
|
||||
cmd->scst_cmd_done(cmd, SCST_CMD_STATE_DEFAULT, SCST_CONTEXT_SAME);
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
static int scst_exec_check_blocking(struct scst_cmd **active_cmd)
|
||||
{
|
||||
struct scst_cmd *cmd = *active_cmd;
|
||||
struct scst_cmd *ref_cmd;
|
||||
int count = 0, rc;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
cmd->state = SCST_CMD_STATE_EXEC_CHECK_BLOCKING;
|
||||
|
||||
if (unlikely(scst_check_blocked_dev(cmd)))
|
||||
goto out;
|
||||
@@ -2760,12 +2748,20 @@ static int scst_exec(struct scst_cmd **active_cmd)
|
||||
/*
|
||||
* To sync with scst_abort_cmd(). The above assignment must
|
||||
* be before SCST_CMD_ABORTED test, done later in
|
||||
* scst_check_local_events(). It's far from here, so the order
|
||||
* __scst_check_local_events(). It's far from here, so the order
|
||||
* is virtually guaranteed, but let's have it just in case.
|
||||
*/
|
||||
smp_mb();
|
||||
|
||||
cmd->scst_cmd_done = scst_cmd_done_local;
|
||||
|
||||
rc = scst_pre_exec_checks(cmd);
|
||||
if (unlikely(rc != SCST_CMD_STATE_RES_CONT_SAME)) {
|
||||
EXTRACHECKS_BUG_ON(rc != SCST_CMD_STATE_RES_CONT_NEXT);
|
||||
EXTRACHECKS_BUG_ON(cmd->state == SCST_CMD_STATE_EXEC_CHECK_BLOCKING);
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmd->state = SCST_CMD_STATE_LOCAL_EXEC;
|
||||
|
||||
rc = scst_do_local_exec(cmd);
|
||||
@@ -2788,7 +2784,7 @@ done:
|
||||
if (cmd == NULL)
|
||||
break;
|
||||
|
||||
cmd->state = SCST_CMD_STATE_START_EXEC;
|
||||
cmd->state = SCST_CMD_STATE_EXEC_CHECK_BLOCKING;
|
||||
|
||||
if (unlikely(scst_check_blocked_dev(cmd)))
|
||||
break;
|
||||
@@ -2796,7 +2792,6 @@ done:
|
||||
__scst_cmd_put(ref_cmd);
|
||||
ref_cmd = cmd;
|
||||
__scst_cmd_get(ref_cmd);
|
||||
|
||||
}
|
||||
|
||||
*active_cmd = cmd;
|
||||
@@ -2814,12 +2809,11 @@ out_put:
|
||||
/* !! At this point sess, dev and tgt_dev can be already freed !! */
|
||||
|
||||
out:
|
||||
EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
|
||||
TRACE_EXIT_RES(res);
|
||||
return res;
|
||||
TRACE_EXIT();
|
||||
return SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
}
|
||||
|
||||
static int scst_send_for_exec(struct scst_cmd **active_cmd)
|
||||
static int scst_exec_check_sn(struct scst_cmd **active_cmd)
|
||||
{
|
||||
int res;
|
||||
struct scst_cmd *cmd = *active_cmd;
|
||||
@@ -2885,7 +2879,7 @@ static int scst_send_for_exec(struct scst_cmd **active_cmd)
|
||||
}
|
||||
|
||||
exec:
|
||||
res = scst_exec(active_cmd);
|
||||
res = scst_exec_check_blocking(active_cmd);
|
||||
|
||||
out:
|
||||
TRACE_EXIT_HRES(res);
|
||||
@@ -2951,7 +2945,6 @@ static int scst_check_sense(struct scst_cmd *cmd)
|
||||
|
||||
cmd->state = SCST_CMD_STATE_REAL_EXEC;
|
||||
cmd->retry = 1;
|
||||
scst_reset_requeued_cmd(cmd);
|
||||
res = 1;
|
||||
goto out;
|
||||
}
|
||||
@@ -3270,35 +3263,35 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
{
|
||||
int res = SCST_CMD_STATE_RES_CONT_SAME;
|
||||
int state;
|
||||
struct scst_device *dev = cmd->dev;
|
||||
struct scst_dev_type *devt = cmd->devt;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
state = SCST_CMD_STATE_PRE_XMIT_RESP;
|
||||
|
||||
if (likely(!scst_is_cmd_fully_local(cmd)) &&
|
||||
likely(dev->handler->dev_done != NULL)) {
|
||||
likely(devt->dev_done != NULL)) {
|
||||
int rc;
|
||||
|
||||
if (unlikely(!dev->handler->dev_done_atomic &&
|
||||
if (unlikely(!devt->dev_done_atomic &&
|
||||
scst_cmd_atomic(cmd))) {
|
||||
/*
|
||||
* It shouldn't be because of the SCST_TGT_DEV_AFTER_*
|
||||
* optimization.
|
||||
*/
|
||||
TRACE_MGMT_DBG("Dev handler %s dev_done() needs thread "
|
||||
"context, rescheduling", dev->handler->name);
|
||||
"context, rescheduling", devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
goto out;
|
||||
}
|
||||
|
||||
TRACE_DBG("Calling dev handler %s dev_done(%p)",
|
||||
dev->handler->name, cmd);
|
||||
devt->name, cmd);
|
||||
scst_set_cur_start(cmd);
|
||||
rc = dev->handler->dev_done(cmd);
|
||||
rc = devt->dev_done(cmd);
|
||||
scst_set_dev_done_time(cmd);
|
||||
TRACE_DBG("Dev handler %s dev_done() returned %d",
|
||||
dev->handler->name, rc);
|
||||
devt->name, rc);
|
||||
if (rc != SCST_CMD_STATE_DEFAULT)
|
||||
state = rc;
|
||||
}
|
||||
@@ -3310,8 +3303,8 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
case SCST_CMD_STATE_PREPARE_SPACE:
|
||||
case SCST_CMD_STATE_RDY_TO_XFER:
|
||||
case SCST_CMD_STATE_TGT_PRE_EXEC:
|
||||
case SCST_CMD_STATE_SEND_FOR_EXEC:
|
||||
case SCST_CMD_STATE_START_EXEC:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_SN:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_BLOCKING:
|
||||
case SCST_CMD_STATE_LOCAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXEC:
|
||||
case SCST_CMD_STATE_PRE_DEV_DONE:
|
||||
@@ -3328,7 +3321,7 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
case SCST_CMD_STATE_NEED_THREAD_CTX:
|
||||
TRACE_DBG("Dev handler %s dev_done() requested "
|
||||
"thread context, rescheduling",
|
||||
dev->handler->name);
|
||||
devt->name);
|
||||
res = SCST_CMD_STATE_RES_NEED_THREAD;
|
||||
goto out;
|
||||
#ifdef CONFIG_SCST_EXTRACHECKS
|
||||
@@ -3336,11 +3329,10 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
if (state >= 0) {
|
||||
PRINT_ERROR("Dev handler %s dev_done() returned "
|
||||
"invalid cmd state %d",
|
||||
dev->handler->name, state);
|
||||
devt->name, state);
|
||||
} else {
|
||||
PRINT_ERROR("Dev handler %s dev_done() returned "
|
||||
"error %d", dev->handler->name,
|
||||
state);
|
||||
"error %d", devt->name, state);
|
||||
}
|
||||
scst_set_cmd_error(cmd,
|
||||
SCST_LOAD_SENSE(scst_sense_hardw_error));
|
||||
@@ -3363,8 +3355,8 @@ static int scst_dev_done(struct scst_cmd *cmd)
|
||||
if (scst_cmd_atomic(cmd)) {
|
||||
switch (state) {
|
||||
case SCST_CMD_STATE_TGT_PRE_EXEC:
|
||||
case SCST_CMD_STATE_SEND_FOR_EXEC:
|
||||
case SCST_CMD_STATE_START_EXEC:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_SN:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_BLOCKING:
|
||||
case SCST_CMD_STATE_LOCAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXEC:
|
||||
TRACE_DBG("Atomic context and redirect, "
|
||||
@@ -3840,6 +3832,7 @@ static int scst_translate_lun(struct scst_cmd *cmd)
|
||||
cmd->tgt_dev = tgt_dev;
|
||||
cmd->cur_order_data = tgt_dev->curr_order_data;
|
||||
cmd->dev = tgt_dev->dev;
|
||||
cmd->devt = tgt_dev->dev->handler;
|
||||
|
||||
res = 0;
|
||||
break;
|
||||
@@ -4109,7 +4102,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
res = scst_tgt_pre_exec(cmd);
|
||||
break;
|
||||
|
||||
case SCST_CMD_STATE_SEND_FOR_EXEC:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_SN:
|
||||
if (tm_dbg_check_cmd(cmd) != 0) {
|
||||
res = SCST_CMD_STATE_RES_CONT_NEXT;
|
||||
TRACE_MGMT_DBG("Skipping cmd %p (tag %llu), "
|
||||
@@ -4117,7 +4110,7 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
(long long unsigned int)cmd->tag);
|
||||
break;
|
||||
}
|
||||
res = scst_send_for_exec(&cmd);
|
||||
res = scst_exec_check_sn(&cmd);
|
||||
EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
|
||||
/*
|
||||
* !! At this point cmd, sess & tgt_dev can already be
|
||||
@@ -4125,8 +4118,8 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
*/
|
||||
break;
|
||||
|
||||
case SCST_CMD_STATE_START_EXEC:
|
||||
res = scst_exec(&cmd);
|
||||
case SCST_CMD_STATE_EXEC_CHECK_BLOCKING:
|
||||
res = scst_exec_check_blocking(&cmd);
|
||||
EXTRACHECKS_BUG_ON(res == SCST_CMD_STATE_RES_NEED_THREAD);
|
||||
/*
|
||||
* !! At this point cmd, sess & tgt_dev can already be
|
||||
@@ -4205,8 +4198,8 @@ void scst_process_active_cmd(struct scst_cmd *cmd, bool atomic)
|
||||
case SCST_CMD_STATE_PREPARE_SPACE:
|
||||
case SCST_CMD_STATE_RDY_TO_XFER:
|
||||
case SCST_CMD_STATE_TGT_PRE_EXEC:
|
||||
case SCST_CMD_STATE_SEND_FOR_EXEC:
|
||||
case SCST_CMD_STATE_START_EXEC:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_SN:
|
||||
case SCST_CMD_STATE_EXEC_CHECK_BLOCKING:
|
||||
case SCST_CMD_STATE_LOCAL_EXEC:
|
||||
case SCST_CMD_STATE_REAL_EXEC:
|
||||
case SCST_CMD_STATE_DEV_DONE:
|
||||
|
||||
Reference in New Issue
Block a user