diff options
-rw-r--r-- | Documentation/scsi/scsi_eh.txt | 8 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 2 | ||||
-rw-r--r-- | drivers/scsi/scsi_error.c | 4 |
3 files changed, 10 insertions, 4 deletions
diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt index 8638f61c8c9d..37eca00796ee 100644 --- a/Documentation/scsi/scsi_eh.txt +++ b/Documentation/scsi/scsi_eh.txt | |||
@@ -263,19 +263,23 @@ scmd->allowed. | |||
263 | 263 | ||
264 | 3. scmd recovered | 264 | 3. scmd recovered |
265 | ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd | 265 | ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd |
266 | - shost->host_failed-- | ||
267 | - clear scmd->eh_eflags | 266 | - clear scmd->eh_eflags |
268 | - scsi_setup_cmd_retry() | 267 | - scsi_setup_cmd_retry() |
269 | - move from local eh_work_q to local eh_done_q | 268 | - move from local eh_work_q to local eh_done_q |
270 | LOCKING: none | 269 | LOCKING: none |
270 | CONCURRENCY: at most one thread per separate eh_work_q to | ||
271 | keep queue manipulation lockless | ||
271 | 272 | ||
272 | 4. EH completes | 273 | 4. EH completes |
273 | ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper | 274 | ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper |
274 | layer of failure. | 275 | layer of failure. May be called concurrently but must have |
276 | a no more than one thread per separate eh_work_q to | ||
277 | manipulate the queue locklessly | ||
275 | - scmd is removed from eh_done_q and scmd->eh_entry is cleared | 278 | - scmd is removed from eh_done_q and scmd->eh_entry is cleared |
276 | - if retry is necessary, scmd is requeued using | 279 | - if retry is necessary, scmd is requeued using |
277 | scsi_queue_insert() | 280 | scsi_queue_insert() |
278 | - otherwise, scsi_finish_command() is invoked for scmd | 281 | - otherwise, scsi_finish_command() is invoked for scmd |
282 | - zero shost->host_failed | ||
279 | LOCKING: queue or finish function performs appropriate locking | 283 | LOCKING: queue or finish function performs appropriate locking |
280 | 284 | ||
281 | 285 | ||
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 961acc788f44..91a9e6af2ec4 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -606,7 +606,7 @@ void ata_scsi_error(struct Scsi_Host *host) | |||
606 | ata_scsi_port_error_handler(host, ap); | 606 | ata_scsi_port_error_handler(host, ap); |
607 | 607 | ||
608 | /* finish or retry handled scmd's and clean up */ | 608 | /* finish or retry handled scmd's and clean up */ |
609 | WARN_ON(host->host_failed || !list_empty(&eh_work_q)); | 609 | WARN_ON(!list_empty(&eh_work_q)); |
610 | 610 | ||
611 | DPRINTK("EXIT\n"); | 611 | DPRINTK("EXIT\n"); |
612 | } | 612 | } |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 984ddcb4786d..1b9c049bd5c5 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1127,7 +1127,6 @@ static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn) | |||
1127 | */ | 1127 | */ |
1128 | void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q) | 1128 | void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q) |
1129 | { | 1129 | { |
1130 | scmd->device->host->host_failed--; | ||
1131 | scmd->eh_eflags = 0; | 1130 | scmd->eh_eflags = 0; |
1132 | list_move_tail(&scmd->eh_entry, done_q); | 1131 | list_move_tail(&scmd->eh_entry, done_q); |
1133 | } | 1132 | } |
@@ -2226,6 +2225,9 @@ int scsi_error_handler(void *data) | |||
2226 | else | 2225 | else |
2227 | scsi_unjam_host(shost); | 2226 | scsi_unjam_host(shost); |
2228 | 2227 | ||
2228 | /* All scmds have been handled */ | ||
2229 | shost->host_failed = 0; | ||
2230 | |||
2229 | /* | 2231 | /* |
2230 | * Note - if the above fails completely, the action is to take | 2232 | * Note - if the above fails completely, the action is to take |
2231 | * individual devices offline and flush the queue of any | 2233 | * individual devices offline and flush the queue of any |