diff options
author | Finn Thain <fthain@telegraphics.com.au> | 2016-01-03 06:05:44 +0100 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2016-01-07 03:43:01 +0100 |
commit | 72064a783b0c24dc4325295ffba949c115aff6d2 (patch) | |
tree | 3c09a60a36559d103b273585b1f5a4b1c568b9d4 /drivers/scsi/atari_NCR5380.c | |
parent | ncr5380: Replace READ_OVERRUNS macro with FLAG_NO_DMA_FIXUPS (diff) | |
download | linux-72064a783b0c24dc4325295ffba949c115aff6d2.tar.xz linux-72064a783b0c24dc4325295ffba949c115aff6d2.zip |
ncr5380: Standardize reselection handling
Bring the two NCR5380_reselect() implementations into agreement.
Replace infinite loops in atari_NCR5380.c with timeouts, as per NCR5380.c.
Remove 'abort' flag in NCR5380.c as per atari_NCR5380.c -- if reselection
fails, there may be no MESSAGE IN phase so don't attempt data transfer.
During selection, don't interfere with the chip registers after a
reselection interrupt intervenes.
Clean up some trivial issues with code style, comments and printk.
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 | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 70398c61fffc..214f43b4baad 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c @@ -1446,11 +1446,9 @@ static int NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) else udelay(2); - if (hostdata->connected) { - NCR5380_write(MODE_REG, MR_BASE); - NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + /* NCR5380_reselect() clears MODE_REG after a reselection interrupt */ + if (!(NCR5380_read(MODE_REG) & MR_ARBITRATE)) return -1; - } dprintk(NDEBUG_ARBITRATION, "scsi%d: won arbitration\n", HOSTNO); @@ -2223,13 +2221,15 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) cmd->scsi_done(cmd); } - NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); /* * Restore phase bits to 0 so an interrupted selection, * arbitration can resume. */ NCR5380_write(TARGET_COMMAND_REG, 0); + /* Enable reselect interrupts */ + NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); + /* ++roman: For Falcon SCSI, release the lock on the * ST-DMA here if no other commands are waiting on the * disconnected queue. @@ -2482,17 +2482,22 @@ static void NCR5380_reselect(struct Scsi_Host *instance) */ NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_BSY); - - while (NCR5380_read(STATUS_REG) & SR_SEL) - ; + if (NCR5380_poll_politely(instance, + STATUS_REG, SR_SEL, 0, 2 * HZ) < 0) { + NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); + return; + } NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); /* * Wait for target to go into MSGIN. */ - while (!(NCR5380_read(STATUS_REG) & SR_REQ)) - ; + if (NCR5380_poll_politely(instance, + STATUS_REG, SR_REQ, SR_REQ, 2 * HZ) < 0) { + do_abort(instance); + return; + } #if defined(CONFIG_SUN3) && defined(REAL_DMA) /* acknowledge toggle to MSGIN */ @@ -2505,15 +2510,21 @@ static void NCR5380_reselect(struct Scsi_Host *instance) data = msg; phase = PHASE_MSGIN; NCR5380_transfer_pio(instance, &phase, &len, &data); + + if (len) { + do_abort(instance); + return; + } #endif if (!(msg[0] & 0x80)) { - printk(KERN_DEBUG "scsi%d: expecting IDENTIFY message, got ", HOSTNO); + shost_printk(KERN_ERR, instance, "expecting IDENTIFY message, got "); spi_print_msg(msg); + printk("\n"); do_abort(instance); return; } - lun = (msg[0] & 0x07); + lun = msg[0] & 0x07; #if defined(SUPPORT_TAGS) && !defined(CONFIG_SUN3) /* If the phase is still MSGIN, the target wants to send some more @@ -2541,7 +2552,7 @@ static void NCR5380_reselect(struct Scsi_Host *instance) for (tmp = (struct scsi_cmnd *) hostdata->disconnected_queue, prev = NULL; tmp; prev = tmp, tmp = NEXT(tmp)) { - if ((target_mask == (1 << tmp->device->id)) && (lun == tmp->device->lun) + if ((target_mask == (1 << tmp->device->id)) && (lun == (u8)tmp->device->lun) #ifdef SUPPORT_TAGS && (tag == tmp->tag) #endif @@ -2559,16 +2570,13 @@ static void NCR5380_reselect(struct Scsi_Host *instance) } if (!tmp) { - printk(KERN_WARNING "scsi%d: warning: target bitmask %02x lun %d " #ifdef SUPPORT_TAGS - "tag %d " -#endif - "not in disconnected_queue.\n", - HOSTNO, target_mask, lun -#ifdef SUPPORT_TAGS - , tag + shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d tag %d not in disconnected queue.\n", + target_mask, lun, tag); +#else + shost_printk(KERN_ERR, instance, "target bitmask 0x%02x lun %d not in disconnected queue.\n", + target_mask, lun); #endif - ); /* * Since we have an established nexus that we can't do anything * with, we must abort it. |