summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/NCR5380.c34
-rw-r--r--drivers/scsi/NCR5380.h1
-rw-r--r--drivers/scsi/arm/cumana_1.c2
-rw-r--r--drivers/scsi/arm/oak.c2
-rw-r--r--drivers/scsi/dmx3191d.c2
-rw-r--r--drivers/scsi/dtc.c2
-rw-r--r--drivers/scsi/g_NCR5380.c2
-rw-r--r--drivers/scsi/pas16.c2
-rw-r--r--drivers/scsi/t128.c2
9 files changed, 35 insertions, 14 deletions
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 78d7858c4404..1f9028a0e7ea 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -777,8 +777,7 @@ static void lprint_opcode(int opcode, struct seq_file *m)
static int NCR5380_init(struct Scsi_Host *instance, int flags)
{
- int i, pass;
- unsigned long timeout;
+ int i;
struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
if(in_interrupt())
@@ -831,18 +830,26 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
}
#endif
+ return 0;
+}
- /*
- * Detect and correct bus wedge problems.
- *
- * If the system crashed, it may have crashed in a state
- * where a SCSI command was still executing, and the
- * SCSI bus is not in a BUS FREE STATE.
- *
- * If this is the case, we'll try to abort the currently
- * established nexus which we know nothing about, and that
- * failing, do a hard reset of the SCSI bus
- */
+/**
+ * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems.
+ * @instance: adapter to check
+ *
+ * If the system crashed, it may have crashed with a connected target and
+ * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the
+ * currently established nexus, which we know nothing about. Failing that
+ * do a bus reset.
+ *
+ * Note that a bus reset will cause the chip to assert IRQ.
+ *
+ * Returns 0 if successful, otherwise -ENXIO.
+ */
+
+static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
+{
+ int pass;
for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
switch (pass) {
@@ -850,7 +857,6 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
case 3:
case 5:
printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
- timeout = jiffies + 5 * HZ;
NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
break;
case 2:
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h
index 24c784140db6..2057eaa66c20 100644
--- a/drivers/scsi/NCR5380.h
+++ b/drivers/scsi/NCR5380.h
@@ -318,6 +318,7 @@ static void NCR5380_print(struct Scsi_Host *instance);
static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
#endif
static int NCR5380_init(struct Scsi_Host *instance, int flags);
+static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
static void NCR5380_exit(struct Scsi_Host *instance);
static void NCR5380_information_transfer(struct Scsi_Host *instance);
#ifndef DONT_USE_INTR
diff --git a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
index 8996a6ccc08f..c7dc65e39cdb 100644
--- a/drivers/scsi/arm/cumana_1.c
+++ b/drivers/scsi/arm/cumana_1.c
@@ -240,6 +240,8 @@ static int cumanascsi1_probe(struct expansion_card *ec,
NCR5380_init(host, 0);
+ NCR5380_maybe_reset_bus(host);
+
priv(host)->ctrl = 0;
writeb(0, priv(host)->base + CTRL);
diff --git a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
index aa5310bef9b7..ca0f31d22f43 100644
--- a/drivers/scsi/arm/oak.c
+++ b/drivers/scsi/arm/oak.c
@@ -145,6 +145,8 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
NCR5380_init(host, 0);
+ NCR5380_maybe_reset_bus(host);
+
ret = scsi_add_host(host, &ec->dev);
if (ret)
goto out_unmap;
diff --git a/drivers/scsi/dmx3191d.c b/drivers/scsi/dmx3191d.c
index 8d2984d7fa9c..2c0fd7641075 100644
--- a/drivers/scsi/dmx3191d.c
+++ b/drivers/scsi/dmx3191d.c
@@ -97,6 +97,8 @@ static int dmx3191d_probe_one(struct pci_dev *pdev,
NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
+ NCR5380_maybe_reset_bus(shost);
+
pci_set_drvdata(pdev, shost);
error = scsi_add_host(shost, &pdev->dev);
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
index 43c1739639ba..02a5532f4267 100644
--- a/drivers/scsi/dtc.c
+++ b/drivers/scsi/dtc.c
@@ -237,6 +237,8 @@ found:
NCR5380_init(instance, 0);
+ NCR5380_maybe_reset_bus(instance);
+
NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */
if (overrides[current_override].irq != IRQ_AUTO)
instance->irq = overrides[current_override].irq;
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 4559fbc7f342..6f5fdf642296 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -422,6 +422,8 @@ static int __init generic_NCR5380_detect(struct scsi_host_template *tpnt)
NCR5380_init(instance, flags);
+ NCR5380_maybe_reset_bus(instance);
+
if (overrides[current_override].irq != IRQ_AUTO)
instance->irq = overrides[current_override].irq;
else
diff --git a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
index e147f5667f27..c316ff7ffef6 100644
--- a/drivers/scsi/pas16.c
+++ b/drivers/scsi/pas16.c
@@ -384,6 +384,8 @@ static int __init pas16_detect(struct scsi_host_template *tpnt)
NCR5380_init(instance, 0);
+ NCR5380_maybe_reset_bus(instance);
+
if (overrides[current_override].irq != IRQ_AUTO)
instance->irq = overrides[current_override].irq;
else
diff --git a/drivers/scsi/t128.c b/drivers/scsi/t128.c
index d06ae1d11ca4..d5e6b676d75e 100644
--- a/drivers/scsi/t128.c
+++ b/drivers/scsi/t128.c
@@ -215,6 +215,8 @@ found:
NCR5380_init(instance, 0);
+ NCR5380_maybe_reset_bus(instance);
+
if (overrides[current_override].irq != IRQ_AUTO)
instance->irq = overrides[current_override].irq;
else