If a timeout error is injected, return 0 from scsi_debug_queuecommand to make the command timeout. For example, the following command would inject timeout error for inquiry(0x12) command for 10 times: error=/sys/kernel/debug/scsi_debug/0:0:0:1/error echo "0 -10 0x12" > $error Signed-off-by: Wenchao Hao <haowenchao2@xxxxxxxxxx> --- drivers/scsi/scsi_debug.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 2c380cddcb84..2d31ae15bd97 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -7714,6 +7714,30 @@ static int sdebug_blk_mq_poll(struct Scsi_Host *shost, unsigned int queue_num) return num_entries; } +static int sdebug_timeout_cmd(struct scsi_cmnd *cmnd) +{ + struct scsi_device *sdp = cmnd->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; + struct sdebug_err_inject *err; + unsigned char *cmd = cmnd->cmnd; + int ret = 0; + + if (devip == NULL) + return 0; + + list_for_each_entry(err, &devip->inject_err_list, list) { + if (err->type == ERR_TMOUT_CMD && + (err->cmd == cmd[0] || err->cmd == 0xff)) { + ret = !!err->cnt; + if (err->cnt < 0) + err->cnt++; + return ret; + } + } + + return 0; +} + static int scsi_debug_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scp) { @@ -7772,6 +7796,12 @@ static int scsi_debug_queuecommand(struct Scsi_Host *shost, if (NULL == devip) goto err_out; } + + if (sdebug_timeout_cmd(scp)) { + scmd_printk(KERN_INFO, scp, "timeout command 0x%x\n", opcode); + return 0; + } + if (unlikely(inject_now && !atomic_read(&sdeb_inject_pending))) atomic_set(&sdeb_inject_pending, 1); -- 2.32.0