scsi: NCR5380: Always re-enable reselection interrupt [Linux 4.9.187]

This Linux kernel change "scsi: NCR5380: Always re-enable reselection interrupt" is included in the Linux 4.9.187 release. This change is authored by Finn Thain <fthain [at] telegraphics.com.au> on Sun Jun 9 11:19:11 2019 +1000. The commit for this change in Linux stable tree is 8e21afa (patch) which is from upstream commit 57f3132. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 57f3132.

scsi: NCR5380: Always re-enable reselection interrupt

commit 57f31326518e98ee4cabf9a04efe00ed57c54147 upstream.

The reselection interrupt gets disabled during selection and must be
re-enabled when hostdata->connected becomes NULL. If it isn't re-enabled a
disconnected command may time-out or the target may wedge the bus while
trying to reselect the host. This can happen after a command is aborted.

Fix this by enabling the reselection interrupt in NCR5380_main() after
calls to NCR5380_select() and NCR5380_information_transfer() return.

Cc: Michael Schmitz <schmitzmic@gmail.com>
Cc: stable@vger.kernel.org # v4.9+
Fixes: 8b00c3d5d40d ("ncr5380: Implement new eh_abort_handler")
Signed-off-by: Finn Thain <fthain@telegraphics.com.au>
Tested-by: Stan Johnson <userm57@yahoo.com>
Tested-by: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

There are 12 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/scsi/NCR5380.c | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 5d6e387..3cfab88 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -813,6 +813,8 @@ static void NCR5380_main(struct work_struct *work)
            NCR5380_information_transfer(instance);
            done = 0;
        }
+       if (!hostdata->connected)
+           NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        spin_unlock_irq(&hostdata->lock);
        if (!done)
            cond_resched();
@@ -1208,8 +1210,6 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
        spin_lock_irq(&hostdata->lock);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
        NCR5380_reselect(instance);
-       if (!hostdata->connected)
-           NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
        goto out;
    }
@@ -1217,7 +1217,6 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
    if (err < 0) {
        spin_lock_irq(&hostdata->lock);
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);

        /* Can't touch cmd if it has been reclaimed by the scsi ML */
        if (!hostdata->selecting)
@@ -1255,7 +1254,6 @@ static struct scsi_cmnd *NCR5380_select(struct Scsi_Host *instance,
    if (err < 0) {
        shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
        NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
-       NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
        goto out;
    }
    if (!hostdata->selecting) {
@@ -1906,9 +1904,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                     */
                    NCR5380_write(TARGET_COMMAND_REG, 0);

-                   /* Enable reselect interrupts */
-                   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
-
                    maybe_release_dma_irq(instance);
                    return;
                case MESSAGE_REJECT:
@@ -1940,8 +1935,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                     */
                    NCR5380_write(TARGET_COMMAND_REG, 0);

-                   /* Enable reselect interrupts */
-                   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
 #ifdef SUN3_SCSI_VME
                    dregs->csr |= CSR_DMA_ENABLE;
 #endif
@@ -2049,7 +2042,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
                    cmd->result = DID_ERROR << 16;
                    complete_cmd(instance, cmd);
                    maybe_release_dma_irq(instance);
-                   NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
                    return;
                }
                msgout = NOP;

Leave a Reply

Your email address will not be published. Required fields are marked *