diff options
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r-- | drivers/scsi/scsi_error.c | 61 |
1 files changed, 25 insertions, 36 deletions
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 30ac116186f5..45c75649b9e0 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -1124,51 +1124,40 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost, | |||
1124 | struct list_head *work_q, | 1124 | struct list_head *work_q, |
1125 | struct list_head *done_q) | 1125 | struct list_head *done_q) |
1126 | { | 1126 | { |
1127 | struct scsi_cmnd *scmd, *tgtr_scmd, *next; | 1127 | LIST_HEAD(tmp_list); |
1128 | unsigned int id = 0; | ||
1129 | int rtn; | ||
1130 | 1128 | ||
1131 | do { | 1129 | list_splice_init(work_q, &tmp_list); |
1132 | tgtr_scmd = NULL; | 1130 | |
1133 | list_for_each_entry(scmd, work_q, eh_entry) { | 1131 | while (!list_empty(&tmp_list)) { |
1134 | if (id == scmd_id(scmd)) { | 1132 | struct scsi_cmnd *next, *scmd; |
1135 | tgtr_scmd = scmd; | 1133 | int rtn; |
1136 | break; | 1134 | unsigned int id; |
1137 | } | 1135 | |
1138 | } | 1136 | scmd = list_entry(tmp_list.next, struct scsi_cmnd, eh_entry); |
1139 | if (!tgtr_scmd) { | 1137 | id = scmd_id(scmd); |
1140 | /* not one exactly equal; find the next highest */ | ||
1141 | list_for_each_entry(scmd, work_q, eh_entry) { | ||
1142 | if (scmd_id(scmd) > id && | ||
1143 | (!tgtr_scmd || | ||
1144 | scmd_id(tgtr_scmd) > scmd_id(scmd))) | ||
1145 | tgtr_scmd = scmd; | ||
1146 | } | ||
1147 | } | ||
1148 | if (!tgtr_scmd) | ||
1149 | /* no more commands, that's it */ | ||
1150 | break; | ||
1151 | 1138 | ||
1152 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset " | 1139 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset " |
1153 | "to target %d\n", | 1140 | "to target %d\n", |
1154 | current->comm, id)); | 1141 | current->comm, id)); |
1155 | rtn = scsi_try_target_reset(tgtr_scmd); | 1142 | rtn = scsi_try_target_reset(scmd); |
1156 | if (rtn == SUCCESS || rtn == FAST_IO_FAIL) { | 1143 | if (rtn != SUCCESS && rtn != FAST_IO_FAIL) |
1157 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { | ||
1158 | if (id == scmd_id(scmd)) | ||
1159 | if (!scsi_device_online(scmd->device) || | ||
1160 | rtn == FAST_IO_FAIL || | ||
1161 | !scsi_eh_tur(tgtr_scmd)) | ||
1162 | scsi_eh_finish_cmd(scmd, | ||
1163 | done_q); | ||
1164 | } | ||
1165 | } else | ||
1166 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset" | 1144 | SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Target reset" |
1167 | " failed target: " | 1145 | " failed target: " |
1168 | "%d\n", | 1146 | "%d\n", |
1169 | current->comm, id)); | 1147 | current->comm, id)); |
1170 | id++; | 1148 | list_for_each_entry_safe(scmd, next, &tmp_list, eh_entry) { |
1171 | } while(id != 0); | 1149 | if (scmd_id(scmd) != id) |
1150 | continue; | ||
1151 | |||
1152 | if ((rtn == SUCCESS || rtn == FAST_IO_FAIL) | ||
1153 | && (!scsi_device_online(scmd->device) || | ||
1154 | rtn == FAST_IO_FAIL || !scsi_eh_tur(scmd))) | ||
1155 | scsi_eh_finish_cmd(scmd, done_q); | ||
1156 | else | ||
1157 | /* push back on work queue for further processing */ | ||
1158 | list_move(&scmd->eh_entry, work_q); | ||
1159 | } | ||
1160 | } | ||
1172 | 1161 | ||
1173 | return list_empty(work_q); | 1162 | return list_empty(work_q); |
1174 | } | 1163 | } |