summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi.c')
-rw-r--r--drivers/scsi/scsi.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 1cb5f7d4f27..a780546eda9 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -113,6 +113,7 @@ const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] = {
"Unknown ",
"RAID ",
"Enclosure ",
+ "Direct-Access-RBC",
};
EXPORT_SYMBOL(scsi_device_types);
@@ -259,8 +260,6 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask)
memset(cmd, 0, sizeof(*cmd));
cmd->device = dev;
- cmd->state = SCSI_STATE_UNUSED;
- cmd->owner = SCSI_OWNER_NOBODY;
init_timer(&cmd->eh_timeout);
INIT_LIST_HEAD(&cmd->list);
spin_lock_irqsave(&dev->list_lock, flags);
@@ -269,6 +268,7 @@ struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int gfp_mask)
} else
put_device(&dev->sdev_gendev);
+ cmd->jiffies_at_alloc = jiffies;
return cmd;
}
EXPORT_SYMBOL(scsi_get_command);
@@ -610,10 +610,6 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
* We will use a queued command if possible, otherwise we will
* emulate the queuing and calling of completion function ourselves.
*/
-
- cmd->state = SCSI_STATE_QUEUED;
- cmd->owner = SCSI_OWNER_LOWLEVEL;
-
atomic_inc(&cmd->device->iorequest_cnt);
/*
@@ -632,7 +628,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
spin_lock_irqsave(host->host_lock, flags);
scsi_cmd_get_serial(host, cmd);
- if (unlikely(test_bit(SHOST_CANCEL, &host->shost_state))) {
+ if (unlikely(host->shost_state == SHOST_DEL)) {
cmd->result = (DID_NO_CONNECT << 16);
scsi_done(cmd);
} else {
@@ -683,7 +679,6 @@ void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, struct scsi_request *sreq)
{
sreq->sr_command = cmd;
- cmd->owner = SCSI_OWNER_MIDLEVEL;
cmd->cmd_len = sreq->sr_cmd_len;
cmd->use_sg = sreq->sr_use_sg;
@@ -719,7 +714,6 @@ void scsi_init_cmd_from_req(struct scsi_cmnd *cmd, struct scsi_request *sreq)
/*
* Start the timer ticking.
*/
- cmd->abort_reason = 0;
cmd->result = 0;
SCSI_LOG_MLQUEUE(3, printk("Leaving scsi_init_cmd_from_req()\n"));
@@ -768,8 +762,6 @@ void __scsi_done(struct scsi_cmnd *cmd)
* Set the serial numbers back to zero
*/
cmd->serial_number = 0;
- cmd->state = SCSI_STATE_BHQUEUE;
- cmd->owner = SCSI_OWNER_BH_HANDLER;
atomic_inc(&cmd->device->iodone_cnt);
if (cmd->result)
@@ -807,9 +799,23 @@ static void scsi_softirq(struct softirq_action *h)
while (!list_empty(&local_q)) {
struct scsi_cmnd *cmd = list_entry(local_q.next,
struct scsi_cmnd, eh_entry);
+ /* The longest time any command should be outstanding is the
+ * per command timeout multiplied by the number of retries.
+ *
+ * For a typical command, this is 2.5 minutes */
+ unsigned long wait_for
+ = cmd->allowed * cmd->timeout_per_command;
list_del_init(&cmd->eh_entry);
disposition = scsi_decide_disposition(cmd);
+ if (disposition != SUCCESS &&
+ time_before(cmd->jiffies_at_alloc + wait_for, jiffies)) {
+ dev_printk(KERN_ERR, &cmd->device->sdev_gendev,
+ "timing out command, waited %lus\n",
+ wait_for/HZ);
+ disposition = SUCCESS;
+ }
+
scsi_log_completion(cmd, disposition);
switch (disposition) {
case SUCCESS:
@@ -890,9 +896,6 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
SCSI_LOG_MLCOMPLETE(4, printk("Notifying upper driver of completion "
"for device %d %x\n", sdev->id, cmd->result));
- cmd->owner = SCSI_OWNER_HIGHLEVEL;
- cmd->state = SCSI_STATE_FINISHED;
-
/*
* We can get here with use_sg=0, causing a panic in the upper level
*/