aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_error.c')
-rw-r--r--drivers/scsi/scsi_error.c61
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}