aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2013-11-11 07:44:54 -0500
committerJames Bottomley <JBottomley@Parallels.com>2013-12-19 10:39:02 -0500
commite494f6a728394ab0df194342549ee20e6f0752df (patch)
tree2cbae9eea944540b2777e40f1787a90b78123334 /drivers/scsi/scsi.c
parent2451079bc2ae1334058be8babd44be03ecfa7041 (diff)
[SCSI] improved eh timeout handler
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the 'eh_abort_handler' LLDD callback. Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler. This patch implements a new scsi_abort_command() function which invokes an asynchronous function scsi_eh_abort_handler() to abort the commands via the usual 'eh_abort_handler'. If abort succeeds the command is either retried or terminated, depending on the number of allowed retries. However, 'eh_eflags' records the abort, so if the retry would fail again the command is pushed onto the error handler without trying to abort it (again); it'll be cleared up from SCSI EH. [hare: smatch detected stray switch fixed] Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index fe0bcb18fb26..2b04a57e0f4f 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -297,6 +297,7 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, gfp_t gfp_mask)
297 297
298 cmd->device = dev; 298 cmd->device = dev;
299 INIT_LIST_HEAD(&cmd->list); 299 INIT_LIST_HEAD(&cmd->list);
300 INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler);
300 spin_lock_irqsave(&dev->list_lock, flags); 301 spin_lock_irqsave(&dev->list_lock, flags);
301 list_add_tail(&cmd->list, &dev->cmd_list); 302 list_add_tail(&cmd->list, &dev->cmd_list);
302 spin_unlock_irqrestore(&dev->list_lock, flags); 303 spin_unlock_irqrestore(&dev->list_lock, flags);
@@ -353,6 +354,8 @@ void scsi_put_command(struct scsi_cmnd *cmd)
353 list_del_init(&cmd->list); 354 list_del_init(&cmd->list);
354 spin_unlock_irqrestore(&cmd->device->list_lock, flags); 355 spin_unlock_irqrestore(&cmd->device->list_lock, flags);
355 356
357 cancel_delayed_work(&cmd->abort_work);
358
356 __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev); 359 __scsi_put_command(cmd->device->host, cmd, &sdev->sdev_gendev);
357} 360}
358EXPORT_SYMBOL(scsi_put_command); 361EXPORT_SYMBOL(scsi_put_command);