diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2016-01-03 16:05:34 +1100 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-01-06 21:42:58 -0500 |
commit | 80d3eb6df46603e0b7e9a7361fe5b98383182c7f (patch) | |
tree | 077f7b114442133ba3fee66ecb992df74ed3975d /drivers/scsi/atari_NCR5380.c | |
parent | f35d34744c85b2ea31a3fe624616c10229ff1fb3 (diff) |
atari_NCR5380: Set do_abort() timeouts
Use timeouts in do_abort() in atari_NCR5380.c instead of infinite loops.
Also fix the kernel-doc comment. Keep the two core driver forks in sync.
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/atari_NCR5380.c')
-rw-r--r-- | drivers/scsi/atari_NCR5380.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 528e0b62fb28..a3c0968c8eef 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -1835,19 +1835,19 @@ static void do_reset(struct Scsi_Host *instance) local_irq_restore(flags); } -/* - * Function : do_abort (Scsi_Host *host) - * - * Purpose : abort the currently established nexus. Should only be - * called from a routine which can drop into a +/** + * do_abort - abort the currently established nexus by going to + * MESSAGE OUT phase and sending an ABORT message. + * @instance: relevant scsi host instance * - * Returns : 0 on success, -1 on failure. + * Returns 0 on success, -1 on failure. */ static int do_abort(struct Scsi_Host *instance) { unsigned char tmp, *msgptr, phase; int len; + int rc; /* Request message out phase */ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); @@ -1862,16 +1862,20 @@ static int do_abort(struct Scsi_Host *instance) * the target sees, so we just handshake. */ - while (!((tmp = NCR5380_read(STATUS_REG)) & SR_REQ)) - ; + rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, SR_REQ, 10 * HZ); + if (rc < 0) + goto timeout; + + tmp = NCR5380_read(STATUS_REG) & PHASE_MASK; NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(tmp)); - if ((tmp & PHASE_MASK) != PHASE_MSGOUT) { - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN | - ICR_ASSERT_ACK); - while (NCR5380_read(STATUS_REG) & SR_REQ) - ; + if (tmp != PHASE_MSGOUT) { + NCR5380_write(INITIATOR_COMMAND_REG, + ICR_BASE | ICR_ASSERT_ATN | ICR_ASSERT_ACK); + rc = NCR5380_poll_politely(instance, STATUS_REG, SR_REQ, 0, 3 * HZ); + if (rc < 0) + goto timeout; NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_ATN); } @@ -1887,6 +1891,10 @@ static int do_abort(struct Scsi_Host *instance) */ return len ? -1 : 0; + +timeout: + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + return -1; } #if defined(REAL_DMA) |