--- /dev/null
+From: James Bottomley <James.Bottomley@HansenPartnership.com>
+Subject: Target reset hangs
+Date: Fri, 12 Sep 2008 16:46:51 -0500
+References: bnc#427267
+
+Actually, turns out it's nothing to do with block timeouts, it's a
+target reset bug.
+
+This loop:
+
+ for (id = 0; id <= shost->max_id; id++) {
+
+Never terminates if shost->max_id is set to ~0, like aic94xx does.
+
+It's also pretty inefficient since you mostly have compact target
+numbers, but the max_id can be very high. The best way would be to sort
+the recovery list by target id and skip them if they're equal, but even
+a worst case O(N^2) traversal is probably OK here.
+
+Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+---
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index ad019ec..94ed262 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1065,10 +1065,10 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
+ struct list_head *done_q)
+ {
+ struct scsi_cmnd *scmd, *tgtr_scmd, *next;
+- unsigned int id;
++ unsigned int id = 0;
+ int rtn;
+
+- for (id = 0; id <= shost->max_id; id++) {
++ do {
+ tgtr_scmd = NULL;
+ list_for_each_entry(scmd, work_q, eh_entry) {
+ if (id == scmd_id(scmd)) {
+@@ -1076,8 +1076,18 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
+ break;
+ }
+ }
++ if (!tgtr_scmd) {
++ /* not one exactly equal; find the next highest */
++ list_for_each_entry(scmd, work_q, eh_entry) {
++ if (scmd_id(scmd) > id &&
++ (!tgtr_scmd ||
++ scmd_id(tgtr_scmd) > scmd_id(scmd)))
++ tgtr_scmd = scmd;
++ }
++ }
+ if (!tgtr_scmd)
+- continue;
++ /* no more commands, that's it */
++ break;
+
+ SCSI_LOG_ERROR_RECOVERY(3, printk("%s: Sending target reset "
+ "to target %d\n",
+@@ -1096,7 +1106,8 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
+ " failed target: "
+ "%d\n",
+ current->comm, id));
+- }
++ id++;
++ } while(id != 0);
+
+ return list_empty(work_q);
+ }
+
+
+
+
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html