diff options
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index afd34a608fe7..b616a6bef44a 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <scsi/scsi_transport.h> | 36 | #include <scsi/scsi_transport.h> |
37 | #include <scsi/scsi_host.h> | 37 | #include <scsi/scsi_host.h> |
38 | #include <scsi/scsi_ioctl.h> | 38 | #include <scsi/scsi_ioctl.h> |
39 | #include <scsi/scsi_dh.h> | ||
39 | #include <scsi/sg.h> | 40 | #include <scsi/sg.h> |
40 | 41 | ||
41 | #include "scsi_priv.h" | 42 | #include "scsi_priv.h" |
@@ -463,11 +464,10 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) | |||
463 | if (scsi_sense_is_deferred(&sshdr)) | 464 | if (scsi_sense_is_deferred(&sshdr)) |
464 | return NEEDS_RETRY; | 465 | return NEEDS_RETRY; |
465 | 466 | ||
466 | if (sdev->scsi_dh_data && sdev->scsi_dh_data->scsi_dh && | 467 | if (sdev->handler && sdev->handler->check_sense) { |
467 | sdev->scsi_dh_data->scsi_dh->check_sense) { | ||
468 | int rc; | 468 | int rc; |
469 | 469 | ||
470 | rc = sdev->scsi_dh_data->scsi_dh->check_sense(sdev, &sshdr); | 470 | rc = sdev->handler->check_sense(sdev, &sshdr); |
471 | if (rc != SCSI_RETURN_NOT_HANDLED) | 471 | if (rc != SCSI_RETURN_NOT_HANDLED) |
472 | return rc; | 472 | return rc; |
473 | /* handler does not care. Drop down to default handling */ | 473 | /* handler does not care. Drop down to default handling */ |
@@ -2178,8 +2178,17 @@ int scsi_error_handler(void *data) | |||
2178 | * We never actually get interrupted because kthread_run | 2178 | * We never actually get interrupted because kthread_run |
2179 | * disables signal delivery for the created thread. | 2179 | * disables signal delivery for the created thread. |
2180 | */ | 2180 | */ |
2181 | while (!kthread_should_stop()) { | 2181 | while (true) { |
2182 | /* | ||
2183 | * The sequence in kthread_stop() sets the stop flag first | ||
2184 | * then wakes the process. To avoid missed wakeups, the task | ||
2185 | * should always be in a non running state before the stop | ||
2186 | * flag is checked | ||
2187 | */ | ||
2182 | set_current_state(TASK_INTERRUPTIBLE); | 2188 | set_current_state(TASK_INTERRUPTIBLE); |
2189 | if (kthread_should_stop()) | ||
2190 | break; | ||
2191 | |||
2183 | if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || | 2192 | if ((shost->host_failed == 0 && shost->host_eh_scheduled == 0) || |
2184 | shost->host_failed != atomic_read(&shost->host_busy)) { | 2193 | shost->host_failed != atomic_read(&shost->host_busy)) { |
2185 | SCSI_LOG_ERROR_RECOVERY(1, | 2194 | SCSI_LOG_ERROR_RECOVERY(1, |