Skip to contentSkip to conversation

Patch "ncr5380: Correctly clear command pointers and lists after bus reset" has been added to the 4.5-stable tree

PATCH [email protected] 1 participant 1 message Apr 9, 2016

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

ncr5380: Correctly clear command pointers and lists after bus reset

to the 4.5-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
ncr5380-correctly-clear-command-pointers-and-lists-after-bus-reset.patch
and it can be found in the queue-4.5 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 1884c2838f31e6bf20f21459ed9921f8c92ed3ef Mon Sep 17 00:00:00 2001

From: Finn Thain <[email protected]>
Date: Tue, 23 Feb 2016 10:07:04 +1100
Subject: ncr5380: Correctly clear command pointers and lists after bus reset

From: Finn Thain <[email protected]>

commit 1884c2838f31e6bf20f21459ed9921f8c92ed3ef upstream.

Commands subject to exception handling are to be returned to the scsi mid-layer. Make sure that the various command pointers and command lists in the low-level driver are correctly cleansed of affected commands.

This fixes some bugs that I accidentally introduced in v4.5-rc1 including the removal of INIT_LIST_HEAD for the 'autosense' and 'disconnected' command lists, and the possible NULL pointer dereference in NCR5380_bus_reset() that was reported by Dan Carpenter.

hostdata->sensing may also point to an affected command so this pointer also has to be cleared. The abort handler calls complete_cmd() to take care of this; let's have the bus reset handler do the same.

The issue queue may also contain an affected command. If so, remove it. This also follows the abort handler logic.

Fixes 62717f537e1b ("ncr5380: Implement new eh_bus_reset_handler")
---
 drivers/scsi/NCR5380.c       |   19 ++++++++++++-------
 drivers/scsi/atari_NCR5380.c |   19 ++++++++++++-------
 2 files changed, 24 insertions(+), 14 deletions(-)
drivers/scsi/NCR5380.c +12 -7
@@ -2450,7 +2450,16 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
-	hostdata->selecting = NULL;
+	if (list_del_cmd(&hostdata->unissued, cmd)) {
+		cmd->result = DID_RESET << 16;
+		cmd->scsi_done(cmd);
+	}
+
+	if (hostdata->selecting) {
+		hostdata->selecting->result = DID_RESET << 16;
+		complete_cmd(instance, hostdata->selecting);
+		hostdata->selecting = NULL;
+	}
 
 	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2458,6 +2467,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->disconnected);
 
 	list_for_each_entry(ncmd, &hostdata->autosense, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2465,6 +2475,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->autosense);
 
 	if (hostdata->connected) {
 		set_host_byte(hostdata->connected, DID_RESET);
@@ -2472,12 +2483,6 @@ static int NCR5380_bus_reset(struct scsi
 		hostdata->connected = NULL;
 	}
 
-	if (hostdata->sensing) {
-		set_host_byte(hostdata->connected, DID_RESET);
-		complete_cmd(instance, hostdata->sensing);
-		hostdata->sensing = NULL;
-	}
-
 	for (i = 0; i < 8; ++i)
 		hostdata->busy[i] = 0;
 #ifdef REAL_DMA
drivers/scsi/atari_NCR5380.c +12 -7
@@ -2646,7 +2646,16 @@ static int NCR5380_bus_reset(struct scsi
 	 * commands!
 	 */
 
-	hostdata->selecting = NULL;
+	if (list_del_cmd(&hostdata->unissued, cmd)) {
+		cmd->result = DID_RESET << 16;
+		cmd->scsi_done(cmd);
+	}
+
+	if (hostdata->selecting) {
+		hostdata->selecting->result = DID_RESET << 16;
+		complete_cmd(instance, hostdata->selecting);
+		hostdata->selecting = NULL;
+	}
 
 	list_for_each_entry(ncmd, &hostdata->disconnected, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2654,6 +2663,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->disconnected);
 
 	list_for_each_entry(ncmd, &hostdata->autosense, list) {
 		struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
@@ -2661,6 +2671,7 @@ static int NCR5380_bus_reset(struct scsi
 		set_host_byte(cmd, DID_RESET);
 		cmd->scsi_done(cmd);
 	}
+	INIT_LIST_HEAD(&hostdata->autosense);
 
 	if (hostdata->connected) {
 		set_host_byte(hostdata->connected, DID_RESET);
@@ -2668,12 +2679,6 @@ static int NCR5380_bus_reset(struct scsi
 		hostdata->connected = NULL;
 	}
 
-	if (hostdata->sensing) {
-		set_host_byte(hostdata->connected, DID_RESET);
-		complete_cmd(instance, hostdata->sensing);
-		hostdata->sensing = NULL;
-	}
-
 #ifdef SUPPORT_TAGS
 	free_all_tags(hostdata);
 #endif

Patches currently in stable-queue which might be from [email protected] are

queue-4.5/ncr5380-correctly-clear-command-pointers-and-lists-after-bus-reset.patch queue-4.5/ncr5380-call-scsi_eh_prep_cmnd-and-scsi_eh_restore_cmnd-as-and-when-appropriate.patch queue-4.5/ncr5380-forget-aborted-commands.patch queue-4.5/ncr5380-dont-release-lock-for-pio-transfer.patch queue-4.5/ncr5380-dont-re-enter-ncr5380_select.patch queue-4.5/ncr5380-fix-ncr5380_select-eh-checks-and-result-handling.patch