summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/dtc.c
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2016-01-03 16:05:40 +1100
committerMartin K. Petersen <martin.petersen@oracle.com>2016-01-06 21:43:00 -0500
commitcd400825c95d4b883232614255c4f35c53bf3582 (patch)
tree76a0a45a2d7844365cc67d49c83742d8e59eeed1 /drivers/scsi/dtc.c
parentd1af9c7f4a69824440d2d755ddc3b861712ef024 (diff)
downloadlinux-cd400825c95d4b883232614255c4f35c53bf3582.tar.bz2
ncr5380: Standardize interrupt handling
Because interrupt handling is crucial to the core driver(s), all wrapper drivers need to agree on this code. This patch removes discrepancies. NCR5380_intr() in NCR5380.c has the following pointless loop that differs from the code in atari_NCR5380.c. done = 1; do { /* ... */ } while (!done); The 'done' flag gets cleared when a reconnected command is to be processed from the work queue. But in NCR5380.c, the flag is also used to cause the interrupt conditions to be re-examined. Perhaps this was because NCR5380_reselect() was expected to cause another interrupt, or perhaps the remaining present interrupt conditions need to be handled after the NCR5380_reselect() call? Actually, both possibilities are bogus, as is the loop itself. It seems have been overlooked in the hit-and-miss removal of scsi host instance list iteration many years ago; see history/history.git commit 491447e1fcff ("[PATCH] next NCR5380 updates") and commit 69e1a9482e57 ("[PATCH] fix up NCR5380 private data"). See also my earlier patch, "Always retry arbitration and selection". The datasheet says, "IRQ can be reset simply by reading the Reset Parity/Interrupt Register". So don't treat the chip IRQ like a level-triggered interrupt. Of the conditions that set the IRQ flag, some are level-triggered and some are edge-triggered, which means IRQ itself must be edge-triggered. Some interrupt conditions are latched and some are not. Before clearing the chip IRQ flag, clear all state that may cause it to be raised. That means clearing the DMA Mode and Busy Monitor bits in the Mode Register and clearing the host ID in the Select Enable register. Also clean up some printk's and some comments. Keep atari_NCR5380.c and NCR5380.c in agreement. Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Ondrej Zary <linux@rainbow-software.org> Tested-by: Michael Schmitz <schmitzmic@gmail.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/dtc.c')
-rw-r--r--drivers/scsi/dtc.c8
1 files changed, 0 insertions, 8 deletions
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
index 60bffb34ecfb..3af4f69c199c 100644
--- a/drivers/scsi/dtc.c
+++ b/drivers/scsi/dtc.c
@@ -334,8 +334,6 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
struct NCR5380_hostdata *hostdata = shost_priv(instance);
i = 0;
- NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
if (instance->irq == NO_IRQ)
NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
else
@@ -357,9 +355,7 @@ static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst,
rtrc(4);
while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
++i;
- NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
rtrc(0);
- NCR5380_read(RESET_PARITY_INTERRUPT_REG);
if (i > hostdata->spin_max_r)
hostdata->spin_max_r = i;
return (0);
@@ -383,9 +379,6 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
int i;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
- NCR5380_read(RESET_PARITY_INTERRUPT_REG);
- NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
- /* set direction (write) */
if (instance->irq == NO_IRQ)
NCR5380_write(DTC_CONTROL_REG, 0);
else
@@ -410,7 +403,6 @@ static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src,
++i;
rtrc(7);
/* Check for parity error here. fixme. */
- NCR5380_write(MODE_REG, 0); /* Clear the operating mode */
rtrc(0);
if (i > hostdata->spin_max_w)
hostdata->spin_max_w = i;