|
@@ -68,19 +68,24 @@ int scsi_eh_scmd_add(struct scsi_cmnd *scmd, int eh_flag)
|
|
|
{
|
|
|
struct Scsi_Host *shost = scmd->device->host;
|
|
|
unsigned long flags;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
if (shost->eh_wait == NULL)
|
|
|
return 0;
|
|
|
|
|
|
spin_lock_irqsave(shost->host_lock, flags);
|
|
|
+ if (scsi_host_set_state(shost, SHOST_RECOVERY))
|
|
|
+ if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY))
|
|
|
+ goto out_unlock;
|
|
|
|
|
|
+ ret = 1;
|
|
|
scmd->eh_eflags |= eh_flag;
|
|
|
list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
|
|
|
- scsi_host_set_state(shost, SHOST_RECOVERY);
|
|
|
shost->host_failed++;
|
|
|
scsi_eh_wakeup(shost);
|
|
|
+ out_unlock:
|
|
|
spin_unlock_irqrestore(shost->host_lock, flags);
|
|
|
- return 1;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -176,8 +181,8 @@ void scsi_times_out(struct scsi_cmnd *scmd)
|
|
|
}
|
|
|
|
|
|
if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {
|
|
|
- panic("Error handler thread not present at %p %p %s %d",
|
|
|
- scmd, scmd->device->host, __FILE__, __LINE__);
|
|
|
+ scmd->result |= DID_TIME_OUT << 16;
|
|
|
+ __scsi_done(scmd);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -196,8 +201,7 @@ int scsi_block_when_processing_errors(struct scsi_device *sdev)
|
|
|
{
|
|
|
int online;
|
|
|
|
|
|
- wait_event(sdev->host->host_wait, (sdev->host->shost_state !=
|
|
|
- SHOST_RECOVERY));
|
|
|
+ wait_event(sdev->host->host_wait, !scsi_host_in_recovery(sdev->host));
|
|
|
|
|
|
online = scsi_device_online(sdev);
|
|
|
|
|
@@ -1441,6 +1445,7 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
|
|
|
static void scsi_restart_operations(struct Scsi_Host *shost)
|
|
|
{
|
|
|
struct scsi_device *sdev;
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
/*
|
|
|
* If the door was locked, we need to insert a door lock request
|
|
@@ -1460,7 +1465,11 @@ static void scsi_restart_operations(struct Scsi_Host *shost)
|
|
|
SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",
|
|
|
__FUNCTION__));
|
|
|
|
|
|
- scsi_host_set_state(shost, SHOST_RUNNING);
|
|
|
+ spin_lock_irqsave(shost->host_lock, flags);
|
|
|
+ if (scsi_host_set_state(shost, SHOST_RUNNING))
|
|
|
+ if (scsi_host_set_state(shost, SHOST_CANCEL))
|
|
|
+ BUG_ON(scsi_host_set_state(shost, SHOST_DEL));
|
|
|
+ spin_unlock_irqrestore(shost->host_lock, flags);
|
|
|
|
|
|
wake_up(&shost->host_wait);
|
|
|
|