diff options
author | Finn Thain <fthain@linux-m68k.org> | 2024-08-07 05:36:28 +0200 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2024-08-13 04:05:49 +0200 |
commit | 086c4802cf99ab7275cd4ec6651f696f2cc61bfa (patch) | |
tree | c72d0c379d431fef10720e3ff87121628fdb44de /drivers/scsi/NCR5380.c | |
parent | scsi: NCR5380: Initialize buffer for MSG IN and STATUS transfers (diff) | |
download | linux-086c4802cf99ab7275cd4ec6651f696f2cc61bfa.tar.xz linux-086c4802cf99ab7275cd4ec6651f696f2cc61bfa.zip |
scsi: NCR5380: Handle BSY signal loss during information transfer phases
Improve robustness by checking for a lost BSY signal during the information
transfer loop. The status register is being polled anyway, so a BSY check
costs nothing. BSY signal loss could be caused by a target error or a
kicked plug etc. A bus reset is another possibility but that is already
handled and hostdata->connected would be NULL.
Tested-by: Stan Johnson <userm57@yahoo.com>
Signed-off-by: Finn Thain <fthain@linux-m68k.org>
Link: https://lore.kernel.org/r/d253dddaf4d9bc17b8ee02ea2b731d92f25b16f1.1723001788.git.fthain@linux-m68k.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/NCR5380.c')
-rw-r--r-- | drivers/scsi/NCR5380.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 4fcb73b727aa..8a9df2ab9569 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -1244,8 +1244,6 @@ out: * is in same phase. * * Also, *phase, *count, *data are modified in place. - * - * XXX Note : handling for bus free may be useful. */ /* @@ -1277,8 +1275,8 @@ static int NCR5380_transfer_pio(struct Scsi_Host *instance, * valid */ - if (NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, - HZ * can_sleep) < 0) + if (NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ | SR_BSY, + SR_REQ | SR_BSY, HZ * can_sleep) < 0) break; dsprintk(NDEBUG_HANDSHAKE, instance, "REQ asserted\n"); @@ -1666,9 +1664,6 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, * Side effects : SCSI things happen, the disconnected queue will be * modified if a command disconnects, *instance->connected will * change. - * - * XXX Note : we need to watch for bus free or a reset condition here - * to recover from an unexpected bus free condition. */ static void NCR5380_information_transfer(struct Scsi_Host *instance) @@ -2009,9 +2004,20 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) NCR5380_dprint(NDEBUG_ANY, instance); } /* switch(phase) */ } else { + int err; + spin_unlock_irq(&hostdata->lock); - NCR5380_poll_politely(hostdata, STATUS_REG, SR_REQ, SR_REQ, HZ); + err = NCR5380_poll_politely(hostdata, STATUS_REG, + SR_REQ, SR_REQ, HZ); spin_lock_irq(&hostdata->lock); + + if (err < 0 && hostdata->connected && + !(NCR5380_read(STATUS_REG) & SR_BSY)) { + scmd_printk(KERN_ERR, hostdata->connected, + "BSY signal lost\n"); + do_reset(instance); + bus_reset_cleanup(instance); + } } } } |