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