summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorFinn Thain <fthain@telegraphics.com.au>2016-01-03 00:05:08 -0500
committerMartin K. Petersen <martin.petersen@oracle.com>2016-01-06 21:42:52 -0500
commitb6488f97d3b5b602a066956e58a1ba282456d79b (patch)
tree1ca8032c303d20869e0955f962c3747fbb297322 /drivers
parentb01ec34895720348dab7eae6bfb28a5799130bce (diff)
ncr5380: Split NCR5380_init() into two functions
This patch splits the NCR5380_init() function into two parts, similar to the scheme used with atari_NCR5380.c. This avoids two problems. Firstly, NCR5380_init() may perform a bus reset, which would cause the chip to assert IRQ. The chip is unable to mask its bus reset interrupt. Drivers can't call request_irq() before calling NCR5380_init(), because initialization must happen before the interrupt handler executes. If driver initialization causes an interrupt it may be problematic on some platforms. To avoid that, first move the bus reset code into NCR5380_maybe_reset_bus(). Secondly, NCR5380_init() contains some board-specific interrupt setup code for the NCR53C400 that does not belong in the core driver. In moving this code, better not re-order interrupt initialization and bus reset. Again, the solution is to move the bus reset code into NCR5380_maybe_reset_bus(). Signed-off-by: Finn Thain <fthain@telegraphics.com.au> Reviewed-by: Hannes Reinecke <hare@suse.com> Tested-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers')
-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)
777 777
778static int NCR5380_init(struct Scsi_Host *instance, int flags) 778static int NCR5380_init(struct Scsi_Host *instance, int flags)
779{ 779{
780 int i, pass; 780 int i;
781 unsigned long timeout;
782 struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; 781 struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;
783 782
784 if(in_interrupt()) 783 if(in_interrupt())
@@ -831,18 +830,26 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
831 NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE); 830 NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
832 } 831 }
833#endif 832#endif
833 return 0;
834}
834 835
835 /* 836/**
836 * Detect and correct bus wedge problems. 837 * NCR5380_maybe_reset_bus - Detect and correct bus wedge problems.
837 * 838 * @instance: adapter to check
838 * If the system crashed, it may have crashed in a state 839 *
839 * where a SCSI command was still executing, and the 840 * If the system crashed, it may have crashed with a connected target and
840 * SCSI bus is not in a BUS FREE STATE. 841 * the SCSI bus busy. Check for BUS FREE phase. If not, try to abort the
841 * 842 * currently established nexus, which we know nothing about. Failing that
842 * If this is the case, we'll try to abort the currently 843 * do a bus reset.
843 * established nexus which we know nothing about, and that 844 *
844 * failing, do a hard reset of the SCSI bus 845 * Note that a bus reset will cause the chip to assert IRQ.
845 */ 846 *
847 * Returns 0 if successful, otherwise -ENXIO.
848 */
849
850static int NCR5380_maybe_reset_bus(struct Scsi_Host *instance)
851{
852 int pass;
846 853
847 for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) { 854 for (pass = 1; (NCR5380_read(STATUS_REG) & SR_BSY) && pass <= 6; ++pass) {
848 switch (pass) { 855 switch (pass) {
@@ -850,7 +857,6 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
850 case 3: 857 case 3:
851 case 5: 858 case 5:
852 printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no); 859 printk(KERN_INFO "scsi%d: SCSI bus busy, waiting up to five seconds\n", instance->host_no);
853 timeout = jiffies + 5 * HZ;
854 NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ); 860 NCR5380_poll_politely(instance, STATUS_REG, SR_BSY, 0, 5*HZ);
855 break; 861 break;
856 case 2: 862 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);
318static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible); 318static int NCR5380_probe_irq(struct Scsi_Host *instance, int possible);
319#endif 319#endif
320static int NCR5380_init(struct Scsi_Host *instance, int flags); 320static int NCR5380_init(struct Scsi_Host *instance, int flags);
321static int NCR5380_maybe_reset_bus(struct Scsi_Host *);
321static void NCR5380_exit(struct Scsi_Host *instance); 322static void NCR5380_exit(struct Scsi_Host *instance);
322static void NCR5380_information_transfer(struct Scsi_Host *instance); 323static void NCR5380_information_transfer(struct Scsi_Host *instance);
323#ifndef DONT_USE_INTR 324#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,
240 240
241 NCR5380_init(host, 0); 241 NCR5380_init(host, 0);
242 242
243 NCR5380_maybe_reset_bus(host);
244
243 priv(host)->ctrl = 0; 245 priv(host)->ctrl = 0;
244 writeb(0, priv(host)->base + CTRL); 246 writeb(0, priv(host)->base + CTRL);
245 247
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)
145 145
146 NCR5380_init(host, 0); 146 NCR5380_init(host, 0);
147 147
148 NCR5380_maybe_reset_bus(host);
149
148 ret = scsi_add_host(host, &ec->dev); 150 ret = scsi_add_host(host, &ec->dev);
149 if (ret) 151 if (ret)
150 goto out_unmap; 152 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,
97 97
98 NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E); 98 NCR5380_init(shost, FLAG_NO_PSEUDO_DMA | FLAG_DTC3181E);
99 99
100 NCR5380_maybe_reset_bus(shost);
101
100 pci_set_drvdata(pdev, shost); 102 pci_set_drvdata(pdev, shost);
101 103
102 error = scsi_add_host(shost, &pdev->dev); 104 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:
237 237
238 NCR5380_init(instance, 0); 238 NCR5380_init(instance, 0);
239 239
240 NCR5380_maybe_reset_bus(instance);
241
240 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */ 242 NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR); /* Enable int's */
241 if (overrides[current_override].irq != IRQ_AUTO) 243 if (overrides[current_override].irq != IRQ_AUTO)
242 instance->irq = overrides[current_override].irq; 244 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)
422 422
423 NCR5380_init(instance, flags); 423 NCR5380_init(instance, flags);
424 424
425 NCR5380_maybe_reset_bus(instance);
426
425 if (overrides[current_override].irq != IRQ_AUTO) 427 if (overrides[current_override].irq != IRQ_AUTO)
426 instance->irq = overrides[current_override].irq; 428 instance->irq = overrides[current_override].irq;
427 else 429 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)
384 384
385 NCR5380_init(instance, 0); 385 NCR5380_init(instance, 0);
386 386
387 NCR5380_maybe_reset_bus(instance);
388
387 if (overrides[current_override].irq != IRQ_AUTO) 389 if (overrides[current_override].irq != IRQ_AUTO)
388 instance->irq = overrides[current_override].irq; 390 instance->irq = overrides[current_override].irq;
389 else 391 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:
215 215
216 NCR5380_init(instance, 0); 216 NCR5380_init(instance, 0);
217 217
218 NCR5380_maybe_reset_bus(instance);
219
218 if (overrides[current_override].irq != IRQ_AUTO) 220 if (overrides[current_override].irq != IRQ_AUTO)
219 instance->irq = overrides[current_override].irq; 221 instance->irq = overrides[current_override].irq;
220 else 222 else