[PATCH 4.5 042/238] ncr5380: Fix NCR5380_select() EH checks and result handling

From: Greg Kroah-Hartman
Date: Sun Apr 10 2016 - 16:47:08 EST


4.5-stable review patch. If anyone has any objections, please let me know.

------------------

From: Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx>

commit ccf6efd78317ef6265829c81a3e1a19f628b1a2d upstream.

Add missing checks for EH abort during arbitration and selection.
Rework the handling of NCR5380_select() result to improve clarity.

Fixes: 707d62b37fbb ("ncr5380: Fix EH during arbitration and selection")
Tested-by: Michael Schmitz <schmitzmic@xxxxxxxxx>
Signed-off-by: Finn Thain <fthain@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>

---
drivers/scsi/NCR5380.c | 16 +++++++++++-----
drivers/scsi/atari_NCR5380.c | 16 +++++++++++-----
2 files changed, 22 insertions(+), 10 deletions(-)

--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -815,15 +815,17 @@ static void NCR5380_main(struct work_str
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
- struct scsi_cmnd *cmd;
int done;

do {
done = 1;

spin_lock_irq(&hostdata->lock);
- while (!hostdata->connected &&
- (cmd = dequeue_next_cmd(instance))) {
+ while (!hostdata->connected && !hostdata->selecting) {
+ struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
+
+ if (!cmd)
+ break;

dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);

@@ -840,8 +842,7 @@ static void NCR5380_main(struct work_str
* entire unit.
*/

- cmd = NCR5380_select(instance, cmd);
- if (!cmd) {
+ if (!NCR5380_select(instance, cmd)) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
} else {
dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance,
@@ -1056,6 +1057,11 @@ static struct scsi_cmnd *NCR5380_select(
/* Reselection interrupt */
goto out;
}
+ if (!hostdata->selecting) {
+ /* Command was aborted */
+ NCR5380_write(MODE_REG, MR_BASE);
+ goto out;
+ }
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,
--- a/drivers/scsi/atari_NCR5380.c
+++ b/drivers/scsi/atari_NCR5380.c
@@ -923,7 +923,6 @@ static void NCR5380_main(struct work_str
struct NCR5380_hostdata *hostdata =
container_of(work, struct NCR5380_hostdata, main_task);
struct Scsi_Host *instance = hostdata->host;
- struct scsi_cmnd *cmd;
int done;

/*
@@ -936,8 +935,11 @@ static void NCR5380_main(struct work_str
done = 1;

spin_lock_irq(&hostdata->lock);
- while (!hostdata->connected &&
- (cmd = dequeue_next_cmd(instance))) {
+ while (!hostdata->connected && !hostdata->selecting) {
+ struct scsi_cmnd *cmd = dequeue_next_cmd(instance);
+
+ if (!cmd)
+ break;

dsprintk(NDEBUG_MAIN, instance, "main: dequeued %p\n", cmd);

@@ -960,8 +962,7 @@ static void NCR5380_main(struct work_str
#ifdef SUPPORT_TAGS
cmd_get_tag(cmd, cmd->cmnd[0] != REQUEST_SENSE);
#endif
- cmd = NCR5380_select(instance, cmd);
- if (!cmd) {
+ if (!NCR5380_select(instance, cmd)) {
dsprintk(NDEBUG_MAIN, instance, "main: select complete\n");
maybe_release_dma_irq(instance);
} else {
@@ -1257,6 +1258,11 @@ static struct scsi_cmnd *NCR5380_select(
/* Reselection interrupt */
goto out;
}
+ if (!hostdata->selecting) {
+ /* Command was aborted */
+ NCR5380_write(MODE_REG, MR_BASE);
+ goto out;
+ }
if (err < 0) {
NCR5380_write(MODE_REG, MR_BASE);
shost_printk(KERN_ERR, instance,