diff --git a/scst/include/scst_const.h b/scst/include/scst_const.h index 43f7358a0..e635a446b 100644 --- a/scst/include/scst_const.h +++ b/scst/include/scst_const.h @@ -575,6 +575,29 @@ enum scst_tg_sup { #define POSITION_LEN_SHORT 20 #define POSITION_LEN_LONG 32 +/************************************************************* + ** Compatibility constants + *************************************************************/ +#ifndef DID_TRANSPORT_DISRUPTED +#define DID_TRANSPORT_DISRUPTED 0xe +#endif + +#ifndef DID_TRANSPORT_FAILFAST +#define DID_TRANSPORT_FAILFAST 0xf +#endif + +#ifndef DID_NEXUS_FAILURE +#define DID_NEXUS_FAILURE 0x11 +#endif + +#ifndef DID_ALLOC_FAILURE +#define DID_ALLOC_FAILURE 0x12 +#endif + +#ifndef DID_MEDIUM_ERROR +#define DID_MEDIUM_ERROR 0x13 +#endif + /************************************************************* ** Various timeouts *************************************************************/ diff --git a/scst/src/scst_targ.c b/scst/src/scst_targ.c index 153c71c7b..579a3857b 100644 --- a/scst/src/scst_targ.c +++ b/scst/src/scst_targ.c @@ -3383,11 +3383,21 @@ static int scst_check_sense(struct scst_cmd *cmd) /* If we had internal bus reset behind us, set the command error UA */ if ((dev->scsi_dev != NULL) && - unlikely(cmd->host_status == DID_RESET) && - ((cmd->op_flags & SCST_SKIP_UA) == 0)) { - TRACE(TRACE_MGMT, "DID_RESET: was_reset=%d host_status=%x", - dev->scsi_dev->was_reset, cmd->host_status); - scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_reset_UA)); + unlikely(cmd->host_status == DID_RESET)) { + if ((cmd->op_flags & SCST_SKIP_UA) == 0) { + TRACE(TRACE_MGMT, "DID_RESET: was_reset=%d host_status=%x", + dev->scsi_dev->was_reset, cmd->host_status); + scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_reset_UA)); + } else { + int sl; + uint8_t sense[SCST_STANDARD_SENSE_LEN]; + TRACE(TRACE_MGMT, "DID_RESET received for device %s, " + "triggering reset UA", dev->virt_name); + sl = scst_set_sense(sense, sizeof(sense), dev->d_sense, + SCST_LOAD_SENSE(scst_sense_reset_UA)); + scst_dev_check_set_UA(dev, NULL, sense, sl); + scst_abort_cmd(cmd, NULL, false, false); + } /* It looks like it is safe to clear was_reset here */ dev->scsi_dev->was_reset = 0; } @@ -3482,8 +3492,23 @@ static bool scst_check_auto_sense(struct scst_cmd *cmd) if ((cmd->host_status == DID_REQUEUE) || (cmd->host_status == DID_IMM_RETRY) || (cmd->host_status == DID_SOFT_ERROR) || - (cmd->host_status == DID_ABORT)) { + (cmd->host_status == DID_BUS_BUSY) || + (cmd->host_status == DID_TRANSPORT_DISRUPTED) || + (cmd->host_status == DID_TRANSPORT_FAILFAST) || + (cmd->host_status == DID_ALLOC_FAILURE)) { scst_set_busy(cmd); + } else if (cmd->host_status == DID_RESET) { + /* Postpone handling to scst_check_sense() */ + } else if ((cmd->host_status == DID_ABORT) || + (cmd->host_status == DID_NO_CONNECT) || + (cmd->host_status == DID_TIME_OUT) || + (cmd->host_status == DID_NEXUS_FAILURE)) { + scst_abort_cmd(cmd, NULL, false, false); + } else if (cmd->host_status == DID_MEDIUM_ERROR) { + if (cmd->data_direction & SCST_DATA_WRITE) + scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_write_error)); + else + scst_set_cmd_error(cmd, SCST_LOAD_SENSE(scst_sense_read_error)); } else { TRACE(TRACE_SCSI|TRACE_MINOR_AND_MGMT_DBG, "Host " "status 0x%x received, returning HARDWARE ERROR "