aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_debug.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2014-11-24 20:18:02 -0500
committerChristoph Hellwig <hch@lst.de>2014-11-25 09:42:56 -0500
commit817fd66beb779dbbe44c46dd11e64d8275efb593 (patch)
treee57cf120d2634f2c55ef42b039ae892aa5209b9e /drivers/scsi/scsi_debug.c
parent22017ed2de64b8f7a2ec0abe59dd6ca92f693391 (diff)
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>
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r--drivers/scsi/scsi_debug.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index a1bca60ae83d..d337eaa128d0 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -209,6 +209,14 @@ static const char *scsi_debug_version_date = "20141022";
209#warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE" 209#warning "Expect DEF_CMD_PER_LUN <= SCSI_DEBUG_CANQUEUE"
210#endif 210#endif
211 211
212struct sdebug_scmd_extra_t {
213 bool inj_recovered;
214 bool inj_transport;
215 bool inj_dif;
216 bool inj_dix;
217 bool inj_short;
218};
219
212static int scsi_debug_add_host = DEF_NUM_HOST; 220static int scsi_debug_add_host = DEF_NUM_HOST;
213static int scsi_debug_ato = DEF_ATO; 221static int scsi_debug_ato = DEF_ATO;
214static int scsi_debug_delay = DEF_DELAY; 222static int scsi_debug_delay = DEF_DELAY;
@@ -248,6 +256,7 @@ static unsigned int scsi_debug_write_same_length = DEF_WRITESAME_LENGTH;
248static bool scsi_debug_removable = DEF_REMOVABLE; 256static bool scsi_debug_removable = DEF_REMOVABLE;
249static bool scsi_debug_clustering; 257static bool scsi_debug_clustering;
250static bool scsi_debug_host_lock = DEF_HOST_LOCK; 258static bool scsi_debug_host_lock = DEF_HOST_LOCK;
259static bool sdebug_any_injecting_opt;
251 260
252static atomic_t sdebug_cmnd_count; 261static atomic_t sdebug_cmnd_count;
253static atomic_t sdebug_completions; 262static atomic_t sdebug_completions;
@@ -3416,6 +3425,16 @@ static ssize_t opts_store(struct device_driver *ddp, const char *buf,
3416 return -EINVAL; 3425 return -EINVAL;
3417opts_done: 3426opts_done:
3418 scsi_debug_opts = opts; 3427 scsi_debug_opts = opts;
3428 if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
3429 sdebug_any_injecting_opt = true;
3430 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
3431 sdebug_any_injecting_opt = true;
3432 else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
3433 sdebug_any_injecting_opt = true;
3434 else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
3435 sdebug_any_injecting_opt = true;
3436 else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
3437 sdebug_any_injecting_opt = true;
3419 atomic_set(&sdebug_cmnd_count, 0); 3438 atomic_set(&sdebug_cmnd_count, 0);
3420 atomic_set(&sdebug_a_tsf, 0); 3439 atomic_set(&sdebug_a_tsf, 0);
3421 return count; 3440 return count;
@@ -4563,6 +4582,41 @@ sdebug_change_qtype(struct scsi_device *sdev, int qtype)
4563 return qtype; 4582 return qtype;
4564} 4583}
4565 4584
4585static int
4586check_inject(struct scsi_cmnd *scp)
4587{
4588 struct sdebug_scmd_extra_t *ep = scsi_cmd_priv(scp);
4589
4590 memset(ep, 0, sizeof(struct sdebug_scmd_extra_t));
4591
4592 if (atomic_inc_return(&sdebug_cmnd_count) >=
4593 abs(scsi_debug_every_nth)) {
4594 atomic_set(&sdebug_cmnd_count, 0);
4595 if (scsi_debug_every_nth < -1)
4596 scsi_debug_every_nth = -1;
4597 if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
4598 return 1; /* ignore command causing timeout */
4599 else if (SCSI_DEBUG_OPT_MAC_TIMEOUT & scsi_debug_opts &&
4600 scsi_medium_access_command(scp))
4601 return 1; /* time out reads and writes */
4602 if (sdebug_any_injecting_opt) {
4603 int opts = scsi_debug_opts;
4604
4605 if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
4606 ep->inj_recovered = true;
4607 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
4608 ep->inj_transport = true;
4609 else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
4610 ep->inj_dif = true;
4611 else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
4612 ep->inj_dix = true;
4613 else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
4614 ep->inj_short = true;
4615 }
4616 }
4617 return 0;
4618}
4619
4566static struct scsi_host_template sdebug_driver_template = { 4620static struct scsi_host_template sdebug_driver_template = {
4567 .show_info = scsi_debug_show_info, 4621 .show_info = scsi_debug_show_info,
4568 .write_info = scsi_debug_write_info, 4622 .write_info = scsi_debug_write_info,
@@ -4589,11 +4643,13 @@ static struct scsi_host_template sdebug_driver_template = {
4589 .use_clustering = DISABLE_CLUSTERING, 4643 .use_clustering = DISABLE_CLUSTERING,
4590 .module = THIS_MODULE, 4644 .module = THIS_MODULE,
4591 .track_queue_depth = 1, 4645 .track_queue_depth = 1,
4646 .cmd_size = sizeof(struct sdebug_scmd_extra_t),
4592}; 4647};
4593 4648
4594static int sdebug_driver_probe(struct device * dev) 4649static int sdebug_driver_probe(struct device * dev)
4595{ 4650{
4596 int error = 0; 4651 int error = 0;
4652 int opts;
4597 struct sdebug_host_info *sdbg_host; 4653 struct sdebug_host_info *sdbg_host;
4598 struct Scsi_Host *hpnt; 4654 struct Scsi_Host *hpnt;
4599 int host_prot; 4655 int host_prot;
@@ -4662,6 +4718,18 @@ static int sdebug_driver_probe(struct device * dev)
4662 else 4718 else
4663 scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_CRC); 4719 scsi_host_set_guard(hpnt, SHOST_DIX_GUARD_CRC);
4664 4720
4721 opts = scsi_debug_opts;
4722 if (SCSI_DEBUG_OPT_RECOVERED_ERR & opts)
4723 sdebug_any_injecting_opt = true;
4724 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & opts)
4725 sdebug_any_injecting_opt = true;
4726 else if (SCSI_DEBUG_OPT_DIF_ERR & opts)
4727 sdebug_any_injecting_opt = true;
4728 else if (SCSI_DEBUG_OPT_DIX_ERR & opts)
4729 sdebug_any_injecting_opt = true;
4730 else if (SCSI_DEBUG_OPT_SHORT_TRANSFER & opts)
4731 sdebug_any_injecting_opt = true;
4732
4665 error = scsi_add_host(hpnt, &sdbg_host->dev); 4733 error = scsi_add_host(hpnt, &sdbg_host->dev);
4666 if (error) { 4734 if (error) {
4667 printk(KERN_ERR "%s: scsi_add_host failed\n", __func__); 4735 printk(KERN_ERR "%s: scsi_add_host failed\n", __func__);