"Unknown ",
"RAID ",
"Enclosure ",
+ "Direct-Access-RBC",
};
EXPORT_SYMBOL(scsi_device_types);
memset(cmd, 0, sizeof(*cmd));
cmd->device = dev;
- cmd->state = SCSI_STATE_UNUSED;
init_timer(&cmd->eh_timeout);
INIT_LIST_HEAD(&cmd->list);
spin_lock_irqsave(&dev->list_lock, flags);
} else
put_device(&dev->sdev_gendev);
+ cmd->jiffies_at_alloc = jiffies;
return cmd;
}
EXPORT_SYMBOL(scsi_get_command);
* 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;
-
atomic_inc(&cmd->device->iorequest_cnt);
/*
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 {
* Set the serial numbers back to zero
*/
cmd->serial_number = 0;
- cmd->state = SCSI_STATE_BHQUEUE;
atomic_inc(&cmd->device->iodone_cnt);
if (cmd->result)
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:
SCSI_LOG_MLCOMPLETE(4, printk("Notifying upper driver of completion "
"for device %d %x\n", sdev->id, cmd->result));
- cmd->state = SCSI_STATE_FINISHED;
-
/*
* We can get here with use_sg=0, causing a panic in the upper level
*/
list_for_each_safe(lh, lh_sf, &active_list) {
scmd = list_entry(lh, struct scsi_cmnd, eh_entry);
list_del_init(lh);
- if (recovery) {
- scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD);
- } else {
+ if (recovery &&
+ !scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD)) {
scmd->result = (DID_ABORT << 16);
scsi_finish_command(scmd);
}