aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/atari_scsi.c
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2014-11-12 00:12:15 -0500
committerChristoph Hellwig <hch@lst.de>2014-11-20 03:11:17 -0500
commite3c3da67340ac7d1d2f630f319eb718474b0d9c3 (patch)
tree3786bf1885076bc2ef606aab34d0f9cd357c7980 /drivers/scsi/atari_scsi.c
parentef1081cbf05b22d3d0e05b267a5559a8cd8e8d4a (diff)
atari_NCR5380: Refactor Falcon locking
Simplify falcon_release_lock_if_possible() by making callers responsible for disabling local IRQ's, which they must do anyway to correctly synchronize the ST DMA "lock" with core driver data structures. Move this synchronization logic to the core driver with which it is tightly coupled. Other LLD's like sun3_scsi and mac_scsi that can make use of this core driver can just stub out the NCR5380_acquire_dma_irq() and NCR5380_release_dma_irq() calls so the compiler will eliminate the ST DMA code. Remove a redundant local_irq_save/restore pair (irq's are disabled for interrupt handlers these days). Revise the locking for atari_scsi_bus_reset(): use local_irq_save/restore() instead of atari_turnoff/turnon_irq(). There is no guarantee that atari_scsi still holds the ST DMA lock during EH, so atari_turnoff/turnon_irq() could end up dropping an IDE or floppy interrupt. Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Tested-by: Michael Schmitz <schmitzmic@gmail.com> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/scsi/atari_scsi.c')
-rw-r--r--drivers/scsi/atari_scsi.c47
1 files changed, 17 insertions, 30 deletions
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index 70c662f9fee4..045112186f84 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -109,6 +109,9 @@
109#define NCR5380_dma_xfer_len(instance, cmd, phase) \ 109#define NCR5380_dma_xfer_len(instance, cmd, phase) \
110 atari_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO)) 110 atari_dma_xfer_len(cmd->SCp.this_residual, cmd, !((phase) & SR_IO))
111 111
112#define NCR5380_acquire_dma_irq(instance) falcon_get_lock()
113#define NCR5380_release_dma_irq(instance) falcon_release_lock()
114
112#include "NCR5380.h" 115#include "NCR5380.h"
113 116
114 117
@@ -448,23 +451,13 @@ static void atari_scsi_fetch_restbytes(void)
448 * connected command and the disconnected queue is empty. 451 * connected command and the disconnected queue is empty.
449 */ 452 */
450 453
451static void falcon_release_lock_if_possible(struct NCR5380_hostdata *hostdata) 454static void falcon_release_lock(void)
452{ 455{
453 unsigned long flags;
454
455 if (IS_A_TT()) 456 if (IS_A_TT())
456 return; 457 return;
457 458
458 local_irq_save(flags); 459 if (stdma_is_locked_by(scsi_falcon_intr))
459
460 if (!hostdata->disconnected_queue &&
461 !hostdata->issue_queue &&
462 !hostdata->connected &&
463 !hostdata->retain_dma_intr &&
464 stdma_is_locked_by(scsi_falcon_intr))
465 stdma_release(); 460 stdma_release();
466
467 local_irq_restore(flags);
468} 461}
469 462
470/* This function manages the locking of the ST-DMA. 463/* This function manages the locking of the ST-DMA.
@@ -787,36 +780,30 @@ static void atari_scsi_falcon_reg_write(unsigned char reg, unsigned char value)
787static int atari_scsi_bus_reset(struct scsi_cmnd *cmd) 780static int atari_scsi_bus_reset(struct scsi_cmnd *cmd)
788{ 781{
789 int rv; 782 int rv;
790 struct NCR5380_hostdata *hostdata = shost_priv(cmd->device->host); 783 unsigned long flags;
784
785 local_irq_save(flags);
791 786
792 /* For doing the reset, SCSI interrupts must be disabled first,
793 * since the 5380 raises its IRQ line while _RST is active and we
794 * can't disable interrupts completely, since we need the timer.
795 */
796 /* And abort a maybe active DMA transfer */
797 if (IS_A_TT()) {
798 atari_turnoff_irq(IRQ_TT_MFP_SCSI);
799#ifdef REAL_DMA 787#ifdef REAL_DMA
788 /* Abort a maybe active DMA transfer */
789 if (IS_A_TT()) {
800 tt_scsi_dma.dma_ctrl = 0; 790 tt_scsi_dma.dma_ctrl = 0;
801#endif
802 } else { 791 } else {
803 atari_turnoff_irq(IRQ_MFP_FSCSI);
804#ifdef REAL_DMA
805 st_dma.dma_mode_status = 0x90; 792 st_dma.dma_mode_status = 0x90;
806 atari_dma_active = 0; 793 atari_dma_active = 0;
807 atari_dma_orig_addr = NULL; 794 atari_dma_orig_addr = NULL;
808#endif
809 } 795 }
796#endif
810 797
811 rv = NCR5380_bus_reset(cmd); 798 rv = NCR5380_bus_reset(cmd);
812 799
813 if (IS_A_TT()) 800 /* The 5380 raises its IRQ line while _RST is active but the ST DMA
814 atari_turnon_irq(IRQ_TT_MFP_SCSI); 801 * "lock" has been released so this interrupt may end up handled by
815 else 802 * floppy or IDE driver (if one of them holds the lock). The NCR5380
816 atari_turnon_irq(IRQ_MFP_FSCSI); 803 * interrupt flag has been cleared already.
804 */
817 805
818 if (rv == SUCCESS) 806 local_irq_restore(flags);
819 falcon_release_lock_if_possible(hostdata);
820 807
821 return rv; 808 return rv;
822} 809}