diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2016-01-03 16:05:40 +1100 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-01-06 21:43:00 -0500 |
commit | cd400825c95d4b883232614255c4f35c53bf3582 (patch) | |
tree | 76a0a45a2d7844365cc67d49c83742d8e59eeed1 /drivers/scsi/dtc.c | |
parent | d1af9c7f4a69824440d2d755ddc3b861712ef024 (diff) | |
download | linux-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.c | 8 |
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; |