mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-20 12:11:26 +00:00
- Fixing case when during SRRs ping-pong between initiator and target HW pending timeout gets triggered and the corresponding command deleted => oops on the next ping-pong turn
- Minor cleanups and fixes git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@1662 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
@@ -2604,6 +2604,9 @@ static int q2t_prepare_srr_ctio(scsi_qla_host_t *ha, struct q2t_cmd *cmd,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cmd->scst_cmd != NULL)
|
||||
scst_update_hw_pending_start(cmd->scst_cmd);
|
||||
|
||||
sc = kzalloc(sizeof(*sc), GFP_ATOMIC);
|
||||
if (sc != NULL) {
|
||||
sc->cmd = cmd;
|
||||
@@ -3604,6 +3607,8 @@ static void q24_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio,
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
TRACE_MGMT_DBG("SRR cmd %p, srr_ui %x", cmd, ntfy->srr_ui);
|
||||
|
||||
switch (ntfy->srr_ui) {
|
||||
case SRR_IU_STATUS:
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
@@ -3702,6 +3707,8 @@ static void q2x_handle_srr(scsi_qla_host_t *ha, struct srr_ctio *sctio,
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
TRACE_MGMT_DBG("SRR cmd %p, srr_ui %x", cmd, ntfy->srr_ui);
|
||||
|
||||
switch (ntfy->srr_ui) {
|
||||
case SRR_IU_STATUS:
|
||||
spin_lock_irq(&ha->hardware_lock);
|
||||
|
||||
@@ -2451,6 +2451,8 @@ static inline void scst_tgt_set_tgt_priv(struct scst_tgt *tgt, void *val)
|
||||
tgt->tgt_priv = val;
|
||||
}
|
||||
|
||||
void scst_update_hw_pending_start(struct scst_cmd *cmd);
|
||||
|
||||
/*
|
||||
* Get/Set functions for session's target private data
|
||||
*/
|
||||
|
||||
@@ -1891,7 +1891,35 @@ out_unlock_tgt:
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Returns 0 to continue, >0 to restart, <0 to break */
|
||||
/**
|
||||
* scst_update_hw_pending_start() - update commands pending start
|
||||
*
|
||||
* Updates the command's hw_pending_start as if it's just started hw pending.
|
||||
* Target drivers should call it if they received reply from this pending
|
||||
* command, but SCST core won't see it.
|
||||
*/
|
||||
void scst_update_hw_pending_start(struct scst_cmd *cmd)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
TRACE_ENTRY();
|
||||
|
||||
/* To sync with scst_check_hw_pending_cmd() */
|
||||
spin_lock_irqsave(&cmd->sess->sess_list_lock, flags);
|
||||
cmd->hw_pending_start = jiffies;
|
||||
TRACE_MGMT_DBG("Updated hw_pending_start to %ld (cmd %p)",
|
||||
cmd->hw_pending_start, cmd);
|
||||
spin_unlock_irqrestore(&cmd->sess->sess_list_lock, flags);
|
||||
|
||||
TRACE_EXIT();
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL(scst_update_hw_pending_start);
|
||||
|
||||
/*
|
||||
* Supposed to be called under sess_list_lock, but can release/reaquire it.
|
||||
* Returns 0 to continue, >0 to restart, <0 to break.
|
||||
*/
|
||||
static int scst_check_hw_pending_cmd(struct scst_cmd *cmd,
|
||||
unsigned long cur_time, unsigned long max_time,
|
||||
struct scst_session *sess, unsigned long *flags,
|
||||
@@ -1904,7 +1932,7 @@ static int scst_check_hw_pending_cmd(struct scst_cmd *cmd,
|
||||
(long)(cur_time - cmd->start_time) / HZ,
|
||||
(long)(cur_time - cmd->hw_pending_start) / HZ);
|
||||
|
||||
if (time_before_eq(cur_time, cmd->start_time + max_time)) {
|
||||
if (time_before(cur_time, cmd->start_time + max_time)) {
|
||||
/* Cmds are ordered, so no need to check more */
|
||||
goto out;
|
||||
}
|
||||
@@ -1915,7 +1943,7 @@ static int scst_check_hw_pending_cmd(struct scst_cmd *cmd,
|
||||
}
|
||||
|
||||
if (time_before(cur_time, cmd->hw_pending_start + max_time)) {
|
||||
/* Cmds are ordered, so no need to check more */
|
||||
res = 0; /* continue */
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -5412,9 +5440,8 @@ int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
if (scsi_status_is_good(rc)) {
|
||||
int q;
|
||||
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI,
|
||||
"Returned control mode page data",
|
||||
buffer, sizeof(buffer));
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI, "Returned control mode "
|
||||
"page data", buffer, sizeof(buffer));
|
||||
|
||||
dev->tst = buffer[4+2] >> 5;
|
||||
q = buffer[4+3] >> 4;
|
||||
@@ -5455,9 +5482,9 @@ int scst_obtain_device_parameters(struct scst_device *dev)
|
||||
*/
|
||||
if (SCST_SENSE_VALID(sense_buffer)) {
|
||||
#endif
|
||||
PRINT_BUFF_FLAG(TRACE_SCSI,
|
||||
"Returned sense data",
|
||||
sense_buffer, sizeof(sense_buffer));
|
||||
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,
|
||||
|
||||
@@ -1395,10 +1395,10 @@ static void scst_do_cmd_done(struct scst_cmd *cmd, int result,
|
||||
scst_alloc_set_sense(cmd, 1, rq_sense, rq_sense_len);
|
||||
}
|
||||
|
||||
TRACE(TRACE_SCSI, "cmd %p, result=%x, cmd->status=%x, resid=%d, "
|
||||
"cmd->msg_status=%x, cmd->host_status=%x, "
|
||||
"cmd->driver_status=%x (cmd %p)", cmd, result, cmd->status, resid,
|
||||
cmd->msg_status, cmd->host_status, cmd->driver_status, cmd);
|
||||
TRACE(TRACE_SCSI, "cmd %p, result %x, cmd->status %x, resid %d, "
|
||||
"cmd->msg_status %x, cmd->host_status %x, "
|
||||
"cmd->driver_status %x", cmd, result, cmd->status, resid,
|
||||
cmd->msg_status, cmd->host_status, cmd->driver_status);
|
||||
|
||||
cmd->completed = 1;
|
||||
|
||||
@@ -1506,6 +1506,11 @@ static void scst_cmd_done_local(struct scst_cmd *cmd, int next_state,
|
||||
|
||||
scst_set_exec_time(cmd);
|
||||
|
||||
TRACE(TRACE_SCSI, "cmd %p, status %x, msg_status %x, host_status %x, "
|
||||
"driver_status %x, resp_data_len %d", cmd, cmd->status,
|
||||
cmd->msg_status, cmd->host_status, cmd->driver_status,
|
||||
cmd->resp_data_len);
|
||||
|
||||
if (next_state == SCST_CMD_STATE_DEFAULT)
|
||||
next_state = SCST_CMD_STATE_PRE_DEV_DONE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user