summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2019-06-08 21:19:11 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-06-20 15:37:03 -0400
commit57f31326518e98ee4cabf9a04efe00ed57c54147 (patch)
treed4eb1cf67ed98ed81e95fe602ba9d3e5b80b789b
parent25fcf94a2fa89dd3e73e965ebb0b38a2a4f72aa4 (diff)
scsi: NCR5380: Always re-enable reselection interrupt
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>
-rw-r--r--drivers/scsi/NCR5380.c12
1 files changed, 2 insertions, 10 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index fe0535affc14..08e3ea8159b3 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -709,6 +709,8 @@ static void NCR5380_main(struct work_struct *work)
709 NCR5380_information_transfer(instance); 709 NCR5380_information_transfer(instance);
710 done = 0; 710 done = 0;
711 } 711 }
712 if (!hostdata->connected)
713 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
712 spin_unlock_irq(&hostdata->lock); 714 spin_unlock_irq(&hostdata->lock);
713 if (!done) 715 if (!done)
714 cond_resched(); 716 cond_resched();
@@ -1110,8 +1112,6 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
1110 spin_lock_irq(&hostdata->lock); 1112 spin_lock_irq(&hostdata->lock);
1111 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); 1113 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1112 NCR5380_reselect(instance); 1114 NCR5380_reselect(instance);
1113 if (!hostdata->connected)
1114 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1115 shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n"); 1115 shost_printk(KERN_ERR, instance, "reselection after won arbitration?\n");
1116 goto out; 1116 goto out;
1117 } 1117 }
@@ -1119,7 +1119,6 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
1119 if (err < 0) { 1119 if (err < 0) {
1120 spin_lock_irq(&hostdata->lock); 1120 spin_lock_irq(&hostdata->lock);
1121 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); 1121 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1122 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1123 1122
1124 /* Can't touch cmd if it has been reclaimed by the scsi ML */ 1123 /* Can't touch cmd if it has been reclaimed by the scsi ML */
1125 if (!hostdata->selecting) 1124 if (!hostdata->selecting)
@@ -1157,7 +1156,6 @@ static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
1157 if (err < 0) { 1156 if (err < 0) {
1158 shost_printk(KERN_ERR, instance, "select: REQ timeout\n"); 1157 shost_printk(KERN_ERR, instance, "select: REQ timeout\n");
1159 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); 1158 NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
1160 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1161 goto out; 1159 goto out;
1162 } 1160 }
1163 if (!hostdata->selecting) { 1161 if (!hostdata->selecting) {
@@ -1826,9 +1824,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
1826 */ 1824 */
1827 NCR5380_write(TARGET_COMMAND_REG, 0); 1825 NCR5380_write(TARGET_COMMAND_REG, 0);
1828 1826
1829 /* Enable reselect interrupts */
1830 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1831
1832 maybe_release_dma_irq(instance); 1827 maybe_release_dma_irq(instance);
1833 return; 1828 return;
1834 case MESSAGE_REJECT: 1829 case MESSAGE_REJECT:
@@ -1860,8 +1855,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
1860 */ 1855 */
1861 NCR5380_write(TARGET_COMMAND_REG, 0); 1856 NCR5380_write(TARGET_COMMAND_REG, 0);
1862 1857
1863 /* Enable reselect interrupts */
1864 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1865#ifdef SUN3_SCSI_VME 1858#ifdef SUN3_SCSI_VME
1866 dregs->csr |= CSR_DMA_ENABLE; 1859 dregs->csr |= CSR_DMA_ENABLE;
1867#endif 1860#endif
@@ -1964,7 +1957,6 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
1964 cmd->result = DID_ERROR << 16; 1957 cmd->result = DID_ERROR << 16;
1965 complete_cmd(instance, cmd); 1958 complete_cmd(instance, cmd);
1966 maybe_release_dma_irq(instance); 1959 maybe_release_dma_irq(instance);
1967 NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
1968 return; 1960 return;
1969 } 1961 }
1970 msgout = NOP; 1962 msgout = NOP;