forked from Minki/linux
scsi_debug: append inject error flags onto scsi_cmnd object
The way the existing scsi_debug command parser associated various inject error flags to a command was difficult to replicate in the table driven parser. This patch adds infrastructure to append those flags to the end of a scsi_cmnd object with the cmd_size host template option. Signed-off-by: Douglas Gilbert <dgilbert@interlog.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
22017ed2de
commit
817fd66beb
@ -209,6 +209,14 @@ static const char *scsi_debug_version_date = "20141022";
|
||||
#warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE"
|
||||
#endif
|
||||
|
||||
struct sdebug_scmd_extra_t {
|
||||
bool inj_recovered;
|
||||
bool inj_transport;
|
||||
bool inj_dif;
|
||||
bool inj_dix;
|
||||
bool inj_short;
|
||||
};
|
||||
|
||||
static int scsi_debug_add_host = DEF_NUM_HOST;
|
||||
static int scsi_debug_ato = DEF_ATO;
|
||||
static int scsi_debug_delay = DEF_DELAY;
|
||||
@ -248,6 +256,7 @@ static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH;
|
||||
static bool scsi_debug_removable = DEF_REMOVABLE;
|
||||
static bool scsi_debug_clustering;
|
||||
static bool scsi_debug_host_lock = DEF_HOST_LOCK;
|
||||
static bool sdebug_any_injecting_opt;
|
||||
|
||||
static atomic_t sdebug_cmnd_count;
|
||||
static atomic_t sdebug_completions;
|
||||
@ -3416,6 +3425,16 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf,
|
||||
return -EINVAL;
|
||||
opts_done:
|
||||
scsi_debug_opts = opts;
|
||||
if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
atomic_set(&sdebug_cmnd_count, 0);
|
||||
atomic_set(&sdebug_a_tsf, 0);
|
||||
return count;
|
||||
@ -4563,6 +4582,41 @@ sdebug_change_qtype(struct scsi_device *sdev, int qtype)
|
||||
return qtype;
|
||||
}
|
||||
|
||||
static int
|
||||
check_inject(struct scsi_cmnd *scp)
|
||||
{
|
||||
struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
|
||||
|
||||
memset(ep, 0, sizeof(struct sdebug_scmd_extra_t));
|
||||
|
||||
if (atomic_inc_return(&sdebug_cmnd_count) >=
|
||||
abs(scsi_debug_every_nth)) {
|
||||
atomic_set(&sdebug_cmnd_count, 0);
|
||||
if (scsi_debug_every_nth < -1)
|
||||
scsi_debug_every_nth = -1;
|
||||
if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
|
||||
return 1; /* ignore command causing timeout */
|
||||
else if (SCSI_DEBUG_OPT_MAC_TIMEOUT & scsi_debug_opts &&
|
||||
scsi_medium_access_command(scp))
|
||||
return 1; /* time out reads and writes */
|
||||
if (sdebug_any_injecting_opt) {
|
||||
int opts = scsi_debug_opts;
|
||||
|
||||
if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
|
||||
ep->inj_recovered = true;
|
||||
else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
|
||||
ep->inj_transport = true;
|
||||
else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
|
||||
ep->inj_dif = true;
|
||||
else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
|
||||
ep->inj_dix = true;
|
||||
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
|
||||
ep->inj_short = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct scsi_host_template sdebug_driver_template = {
|
||||
.show_info = scsi_debug_show_info,
|
||||
.write_info = scsi_debug_write_info,
|
||||
@ -4589,11 +4643,13 @@ static struct scsi_host_template sdebug_driver_template = {
|
||||
.use_clustering = DISABLE_CLUSTERING,
|
||||
.module = THIS_MODULE,
|
||||
.track_queue_depth = 1,
|
||||
.cmd_size = sizeof(struct sdebug_scmd_extra_t),
|
||||
};
|
||||
|
||||
static int sdebug_driver_probe(struct device * dev)
|
||||
{
|
||||
int error = 0;
|
||||
int opts;
|
||||
struct sdebug_host_info *sdbg_host;
|
||||
struct Scsi_Host *hpnt;
|
||||
int host_prot;
|
||||
@ -4662,6 +4718,18 @@ static int sdebug_driver_probe(struct device * dev)
|
||||
else
|
||||
scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_CRC);
|
||||
|
||||
opts = scsi_debug_opts;
|
||||
if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
|
||||
sdebug_any_injecting_opt = true;
|
||||
|
||||
error = scsi_add_host(hpnt, &sdbg_host->dev);
|
||||
if (error) {
|
||||
printk(KERN_ERR "%s: scsi_add_host failed\n", __func__);
|
||||
|
Loading…
Reference in New Issue
Block a user