Commit 6b0e87a6 authored by Finn Thain's avatar Finn Thain Committed by Martin K. Petersen

scsi: NCR5380: Check for bus reset

The SR_RST bit isn't latched. Hence, detecting a bus reset isn't reliable.
When it is detected, the right thing to do is to drop all connected and
disconnected commands. The code for that is already present so refactor it and
call it when SR_RST is set.
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent ca694afa
...@@ -131,6 +131,7 @@ ...@@ -131,6 +131,7 @@
static int do_abort(struct Scsi_Host *); static int do_abort(struct Scsi_Host *);
static void do_reset(struct Scsi_Host *); static void do_reset(struct Scsi_Host *);
static void bus_reset_cleanup(struct Scsi_Host *);
/** /**
* initialize_SCp - init the scsi pointer field * initialize_SCp - init the scsi pointer field
...@@ -883,7 +884,14 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id) ...@@ -883,7 +884,14 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id)
/* Probably Bus Reset */ /* Probably Bus Reset */
NCR5380_read(RESET_PARITY_INTERRUPT_REG); NCR5380_read(RESET_PARITY_INTERRUPT_REG);
if (sr & SR_RST) {
/* Certainly Bus Reset */
shost_printk(KERN_WARNING, instance,
"bus reset interrupt\n");
bus_reset_cleanup(instance);
} else {
dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n"); dsprintk(NDEBUG_INTR, instance, "unknown interrupt\n");
}
#ifdef SUN3_SCSI_VME #ifdef SUN3_SCSI_VME
dregs->csr |= CSR_DMA_ENABLE; dregs->csr |= CSR_DMA_ENABLE;
#endif #endif
...@@ -2305,31 +2313,12 @@ static int NCR5380_abort(struct scsi_cmnd *cmd) ...@@ -2305,31 +2313,12 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
} }
/** static void bus_reset_cleanup(struct Scsi_Host *instance)
* NCR5380_host_reset - reset the SCSI host
* @cmd: SCSI command undergoing EH
*
* Returns SUCCESS
*/
static int NCR5380_host_reset(struct scsi_cmnd *cmd)
{ {
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = shost_priv(instance); struct NCR5380_hostdata *hostdata = shost_priv(instance);
int i; int i;
unsigned long flags;
struct NCR5380_cmd *ncmd; struct NCR5380_cmd *ncmd;
spin_lock_irqsave(&hostdata->lock, flags);
#if (NDEBUG & NDEBUG_ANY)
shost_printk(KERN_INFO, instance, __func__);
#endif
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
do_reset(instance);
/* reset NCR registers */ /* reset NCR registers */
NCR5380_write(MODE_REG, MR_BASE); NCR5380_write(MODE_REG, MR_BASE);
NCR5380_write(TARGET_COMMAND_REG, 0); NCR5380_write(TARGET_COMMAND_REG, 0);
...@@ -2341,14 +2330,6 @@ static int NCR5380_host_reset(struct scsi_cmnd *cmd) ...@@ -2341,14 +2330,6 @@ static int NCR5380_host_reset(struct scsi_cmnd *cmd)
* commands! * commands!
*/ */
list_for_each_entry(ncmd, &hostdata->unissued, list) {
struct scsi_cmnd *cmd = NCR5380_to_scmd(ncmd);
cmd->result = DID_RESET << 16;
cmd->scsi_done(cmd);
}
INIT_LIST_HEAD(&hostdata->unissued);
if (hostdata->selecting) { if (hostdata->selecting) {
hostdata->selecting->result = DID_RESET << 16; hostdata->selecting->result = DID_RESET << 16;
complete_cmd(instance, hostdata->selecting); complete_cmd(instance, hostdata->selecting);
...@@ -2382,6 +2363,41 @@ static int NCR5380_host_reset(struct scsi_cmnd *cmd) ...@@ -2382,6 +2363,41 @@ static int NCR5380_host_reset(struct scsi_cmnd *cmd)
queue_work(hostdata->work_q, &hostdata->main_task); queue_work(hostdata->work_q, &hostdata->main_task);
maybe_release_dma_irq(instance); maybe_release_dma_irq(instance);
}
/**
* NCR5380_host_reset - reset the SCSI host
* @cmd: SCSI command undergoing EH
*
* Returns SUCCESS
*/
static int NCR5380_host_reset(struct scsi_cmnd *cmd)
{
struct Scsi_Host *instance = cmd->device->host;
struct NCR5380_hostdata *hostdata = shost_priv(instance);
unsigned long flags;
struct NCR5380_cmd *ncmd;
spin_lock_irqsave(&hostdata->lock, flags);
#if (NDEBUG & NDEBUG_ANY)
shost_printk(KERN_INFO, instance, __func__);
#endif
NCR5380_dprint(NDEBUG_ANY, instance);
NCR5380_dprint_phase(NDEBUG_ANY, instance);
list_for_each_entry(ncmd, &hostdata->unissued, list) {
struct scsi_cmnd *scmd = NCR5380_to_scmd(ncmd);
scmd->result = DID_RESET << 16;
scmd->scsi_done(scmd);
}
INIT_LIST_HEAD(&hostdata->unissued);
do_reset(instance);
bus_reset_cleanup(instance);
spin_unlock_irqrestore(&hostdata->lock, flags); spin_unlock_irqrestore(&hostdata->lock, flags);
return SUCCESS; return SUCCESS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment