ncr5380: Fix NCR5380_select() EH checks and result handling
authorFinn Thain <fthain@telegraphics.com.au>
Mon, 22 Feb 2016 23:07:08 +0000 (10:07 +1100)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 1 Mar 2016 14:38:50 +0000 (09:38 -0500)
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@gmail.com>
Cc: <stable@vger.kernel.org> # 4.5
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/NCR5380.c
drivers/scsi/atari_NCR5380.c

index b1b3fac839bcb02382df30b64a789b122eaf8cc5..e8e579ad3d54e4a23ea22b467a8879b47ec44356 100644 (file)
@@ -815,15 +815,17 @@ static void NCR5380_main(struct work_struct *work)
        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_struct *work)
                         * 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(struct Scsi_Host *instance,
                /* 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,
index 5629369b7981757225bd1575bcb11ba76e6d2b8d..a36c11be2b6f2a5340a686ec75462aa1fa52c50e 100644 (file)
@@ -923,7 +923,6 @@ static void NCR5380_main(struct work_struct *work)
        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_struct *work)
                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_struct *work)
 #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(struct Scsi_Host *instance,
                /* 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,