summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/esp.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-09-12 01:29:55 +0000
commit545f435ebcfd94a1e7c20b46efe81b4d6ac4e698 (patch)
treee9ce4bc598d06374bda906f18365984bf22a526a /drivers/scsi/esp.c
parent4291a610eef89d0d5c69d9a10ee6560e1aa36c74 (diff)
Merge with Linux 2.1.55. More bugfixes and goodies from my private
CVS archive.
Diffstat (limited to 'drivers/scsi/esp.c')
-rw-r--r--drivers/scsi/esp.c80
1 files changed, 50 insertions, 30 deletions
diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c
index b479cc9fc..f1be3e5b4 100644
--- a/drivers/scsi/esp.c
+++ b/drivers/scsi/esp.c
@@ -12,6 +12,7 @@
* 3) Add tagged queueing.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/types.h>
@@ -34,6 +35,7 @@
#include <asm/pgtable.h>
#include <asm/oplib.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/idprom.h>
#define DEBUG_ESP
@@ -642,6 +644,9 @@ static inline void esp_bootup_reset(struct Sparc_ESP *esp, struct Sparc_ESP_regs
*/
__initfunc(int esp_detect(Scsi_Host_Template *tpnt))
{
+#ifdef __sparc_v9__
+ struct devid_cookie dcookie;
+#endif
struct Sparc_ESP *esp, *elink;
struct Scsi_Host *esp_host;
struct linux_sbus *sbus;
@@ -655,8 +660,13 @@ __initfunc(int esp_detect(Scsi_Host_Template *tpnt))
int esp_node, i;
espchain = 0;
- if(!SBus_chain)
+ if(!SBus_chain) {
+#ifdef CONFIG_PCI
+ return 0;
+#else
panic("No SBUS in esp_detect()");
+#endif
+ }
for_each_sbus(sbus) {
for_each_sbusdev(sbdev_iter, sbus) {
struct linux_sbus_device *espdma = 0;
@@ -782,6 +792,7 @@ __initfunc(int esp_detect(Scsi_Host_Template *tpnt))
esp->edev->reg_addrs[0].reg_size;
esp->ehost->irq = esp->irq = esp->edev->irqs[0].pri;
+#ifndef __sparc_v9__
/* Allocate the irq only if necessary */
for_each_esp(elink) {
if((elink != esp) && (esp->irq == elink->irq)) {
@@ -793,6 +804,22 @@ __initfunc(int esp_detect(Scsi_Host_Template *tpnt))
panic("Cannot acquire ESP irq line");
esp_irq_acquired:
printk("esp%d: IRQ %d ", esp->esp_id, esp->ehost->irq);
+#else
+ /* On Ultra we must always call request_irq for each
+ * esp, so that imap registers get setup etc.
+ */
+ dcookie.real_dev_id = esp;
+ dcookie.imap = dcookie.iclr = 0;
+ dcookie.pil = -1;
+ dcookie.bus_cookie = sbus;
+ if(request_irq(esp->ehost->irq, esp_intr,
+ (SA_SHIRQ | SA_SBUS | SA_DCOOKIE),
+ "Sparc ESP SCSI", &dcookie))
+ panic("Cannot acquire ESP irq line");
+ esp->ehost->irq = esp->irq = dcookie.ret_ino;
+ printk("esp%d: INO[%x] IRQ %d ",
+ esp->esp_id, esp->ehost->irq, dcookie.ret_pil);
+#endif
/* Figure out our scsi ID on the bus */
esp->scsi_id = prom_getintdefault(esp->prom_node,
@@ -2323,11 +2350,6 @@ static inline int esp_do_data_finale(struct Sparc_ESP *esp,
/* Please go to msgout phase, please please please... */
ESPLOG(("esp%d: !BSERV after data, probably to msgout\n",
esp->esp_id));
-#ifdef __SMP__
- ESPLOG(("esp%d: local_irq_count[%x:%x:%x:%x]\n", esp->esp_id,
- local_irq_count[0], local_irq_count[1],
- local_irq_count[2], local_irq_count[3]));
-#endif
return esp_do_phase_determine(esp, eregs, dregs);
}
@@ -2410,11 +2432,6 @@ static inline int esp_do_data_finale(struct Sparc_ESP *esp,
ESPLOG(("esp%d: use_sg=%d ptr=%p this_residual=%d\n",
esp->esp_id,
SCptr->use_sg, SCptr->SCp.ptr, SCptr->SCp.this_residual));
-#ifdef __SMP__
- ESPLOG(("esp%d: local_irq_count[%x:%x:%x:%x]\n", esp->esp_id,
- local_irq_count[0], local_irq_count[1],
- local_irq_count[2], local_irq_count[3]));
-#endif
bytes_sent = 0;
}
@@ -4021,6 +4038,8 @@ esp_handle_done:
return;
}
+#ifndef __sparc_v9__
+
#ifndef __SMP__
static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
{
@@ -4031,14 +4050,7 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
repeat:
again = 0;
for_each_esp(esp) {
- /* XXX Ultra: This is gross, what we really need
- * XXX is a sbusirq_to_sparc_pil() function, call
- * XXX that and stick the result in the esp soft
- * XXX state structure. -DaveM
- */
-#ifndef __sparc_v9__
if((esp->irq & 0xf) == irq) {
-#endif
if(DMA_IRQ_P(esp->dregs)) {
again = 1;
@@ -4050,23 +4062,12 @@ repeat:
DMA_INTSON(esp->dregs);
}
-#ifndef __sparc_v9__
}
-#endif
}
if(again)
goto repeat;
}
#else
-
-/* XXX Gross hack for sun4u SMP, fix it right later... -DaveM */
-#ifdef __sparc_v9__
-extern unsigned char ino_to_pil[];
-#define INO_TO_PIL(esp) (ino_to_pil[(esp)->irq])
-#else
-#define INO_TO_PIL(esp) ((esp)->irq & 0xf)
-#endif
-
/* For SMP we only service one ESP on the list list at our IRQ level! */
static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
{
@@ -4074,7 +4075,7 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
/* Handle all ESP interrupts showing at this IRQ level. */
for_each_esp(esp) {
- if(INO_TO_PIL(esp) == irq) {
+ if(((esp)->irq & 0xf) == irq) {
if(DMA_IRQ_P(esp->dregs)) {
DMA_INTSOFF(esp->dregs);
@@ -4090,3 +4091,22 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
}
}
#endif
+
+#else /* __sparc_v9__ */
+
+static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs)
+{
+ struct Sparc_ESP *esp = dev_id;
+
+ if(DMA_IRQ_P(esp->dregs)) {
+ DMA_INTSOFF(esp->dregs);
+
+ ESPIRQ(("I[%d:%d](", smp_processor_id(), esp->esp_id));
+ esp_handle(esp);
+ ESPIRQ((")"));
+
+ DMA_INTSON(esp->dregs);
+ }
+}
+
+#endif