patch-2.2.0-pre5 linux/arch/m68k/mac/macints.c
Next file: linux/arch/m68k/vmlinux.lds
Previous file: linux/arch/m68k/mac/macboing.c
Back to the patch index
Back to the overall index
- Lines: 317
- Date:
Tue Jan 5 11:20:43 1999
- Orig file:
v2.2.0-pre4/linux/arch/m68k/mac/macints.c
- Orig date:
Tue Dec 22 14:16:54 1998
diff -u --recursive --new-file v2.2.0-pre4/linux/arch/m68k/mac/macints.c linux/arch/m68k/mac/macints.c
@@ -163,6 +163,13 @@
static unsigned long *mac_irqs[8];
/*
+ * Some special nutcases ...
+ */
+
+static unsigned long mac_ide_irqs = 0;
+static unsigned long nubus_stuck_events = 0;
+
+/*
* VIA/RBV/OSS/PSC register base pointers
*/
@@ -217,9 +224,13 @@
static void via_do_nubus(int slot, void *via, struct pt_regs *regs);
/* #define DEBUG_MACINTS */
-/* #define DEBUG_NUBUS_INT */
+
+#define DEBUG_SPURIOUS
+#define DEBUG_NUBUS_SPURIOUS
+#define DEBUG_NUBUS_INT
+
/* #define DEBUG_VIA */
-/* #define DEBUG_VIA_NUBUS */
+#define DEBUG_VIA_NUBUS
void mac_init_IRQ(void)
{
@@ -351,6 +362,12 @@
mac_irqs[7] = &nubus_irqs[0];
/*
+ * Nubus Macs: turn off the Nubus dispatch interrupt for now
+ */
+
+ mac_turnoff_irq(IRQ_MAC_NUBUS);
+
+ /*
* AV Macs: shutup the PSC ints
*/
if (macintosh_config->ident == MAC_MODEL_C660
@@ -430,8 +447,10 @@
return 0;
}
- /* add similar hack for Nubus pseudo-irq here - hide nubus_request_irq */
-
+ /*
+ * code below: only for VIA irqs currently
+ * add similar hack for Nubus pseudo-irq here - hide nubus_request_irq
+ */
via = (volatile unsigned char *) via_table[srcidx];
if (!via)
return -EINVAL;
@@ -697,12 +716,18 @@
return (pending);
}
+/*
+ * for /proc/interrupts: log interrupt stats broken down by
+ * autovector int first, then by actual interrupt source.
+ */
+
int mac_get_irq_list (char *buf)
{
int i, len = 0;
int srcidx, irqidx;
for (i = VIA1_SOURCE_BASE; i < NUM_MAC_SOURCES+8; ++i) {
+ /* XXX fixme: IRQ_SRC_MASK should cover VIA1 - Nubus */
srcidx = ((i & IRQ_SRC_MASK)>>3) - 1;
irqidx = (i & IRQ_IDX_MASK);
@@ -767,6 +792,32 @@
}
if (num_spurious)
len += sprintf(buf+len, "spurio.: %10u\n", num_spurious);
+
+ /*
+ * XXX Fixme: Nubus sources are never logged above ...
+ */
+
+ len += sprintf(buf+len, "Nubus interrupts:\n");
+
+ for (i = 0; i < 7; i++) {
+ if (nubus_handler[i].handler == nubus_wtf)
+ continue;
+ len += sprintf(buf+len, "nubus %01X: %10lu ",
+ i+9,
+ nubus_irqs[i]);
+ len += sprintf(buf+len, "%s\n",
+ nubus_param[i].devname);
+
+ }
+ len += sprintf(buf+len, "nubus spurious ints: %10lu\n",
+ nubus_irqs[7]);
+ len += sprintf(buf+len, "nubus stuck events : %10lu\n",
+ nubus_stuck_events);
+#ifdef CONFIG_BLK_DEV_IDE
+ len += sprintf(buf+len, "nubus/IDE interrupt: %10lu\n",
+ mac_ide_irqs);
+#endif
+
return len;
}
@@ -787,8 +838,9 @@
void mac_default_handler(int irq, void *dev_id, struct pt_regs *regs)
{
-#ifdef DEBUG_VIA
- printk("Unexpected IRQ %d on device %p\n", irq, dev_id);
+#ifdef DEBUG_SPURIOUS
+ if (console_loglevel > 6)
+ printk("Unexpected IRQ %d on device %p\n", irq, dev_id);
#endif
}
@@ -864,6 +916,18 @@
}
/*
+ * Unexpected via interrupt
+ */
+
+void via_wtf(int slot, void *via, struct pt_regs *regs)
+{
+#ifdef DEBUG_SPURIOUS
+ if (console_loglevel > 6)
+ printk("Unexpected nubus event %d on via %p\n",slot,via);
+#endif
+}
+
+/*
* The generic VIA interrupt routines (shamelessly stolen from Alan Cox's
* via6522.c :-), disable/pending masks added.
* The int *viaidx etc. is just to keep the prototype happy ...
@@ -1118,17 +1182,6 @@
}
/*
- * Unexpected via interrupt
- */
-
-void via_wtf(int slot, void *via, struct pt_regs *regs)
-{
-#ifdef DEBUG_VIA
- printk("Unexpected event %d on via %p\n",slot,via);
-#endif
-}
-
-/*
* Nubus / SCSI interrupts; OSS style
* The OSS is even more different than the RBV. OSS appears to stand for
* Obscenely Screwed Silicon ...
@@ -1267,8 +1320,9 @@
void nubus_wtf(int slot, void *via, struct pt_regs *regs)
{
-#ifdef DEBUG_VIA_NUBUS
- printk("Unexpected interrupt on nubus slot %d\n",slot);
+#ifdef DEBUG_NUBUS_SPURIOUS
+ if (console_loglevel > 6)
+ printk("Unexpected interrupt on nubus slot %d\n",slot);
#endif
}
@@ -1282,9 +1336,10 @@
int i;
/* 1+2: compatibility with PSC ! */
for (i = 1; i < 3; i++) /* currently only these two used */
- if (scc_handler[i].handler != mac_default_handler)
+ if (scc_handler[i].handler != mac_default_handler) {
(scc_handler[i].handler)(i, scc_handler[i].dev_id, regs);
-
+ scc_irqs[i]++;
+ }
}
/*
@@ -1426,6 +1481,7 @@
if (!nubus_active && !via2_is_oss) {
request_irq(IRQ_MAC_NUBUS, via_do_nubus, IRQ_FLG_LOCK,
"nubus dispatch", via_do_nubus);
+ mac_turnon_irq(IRQ_MAC_NUBUS);
}
nubus_active|=1<<slot;
@@ -1475,6 +1531,7 @@
* IDE interrupt hook
*/
extern void (*mac_ide_intr_hook)(int, void *, struct pt_regs *);
+extern int (*mac_ide_irq_p_hook)(void);
#endif
/*
@@ -1482,13 +1539,13 @@
*/
static void via_do_nubus(int slot, void *via, struct pt_regs *regs)
{
- unsigned char map;
+ unsigned char map, allints;
int i;
int ct=0;
-
-/* printk("nubus interrupt\n");*/
+ int ide_pending = 0;
/* lock the nubus interrupt */
+ /* That's just 'clear Nubus IRQ bit in VIA2' BTW. Pretty obsolete ? */
if (via2_is_rbv)
via_write(rbv_regp, rIFR, 0x82);
else
@@ -1496,37 +1553,69 @@
#ifdef CONFIG_BLK_DEV_MAC_IDE
/* IDE hack */
- if (mac_ide_intr_hook)
+ if (mac_ide_intr_hook) {
/* 'slot' is lacking the machspec bit in 2.0 */
/* need to pass proper dev_id = hwgroup here */
mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs);
+ mac_ide_irqs++;
+ }
#endif
while(1)
{
if (via2_is_rbv)
- map = ~via_read(rbv_regp, rBufA);
+ allints = ~via_read(rbv_regp, rBufA);
else
- map = ~via_read(via2_regp, vBufA);
+ allints = ~via_read(via2_regp, vBufA);
-#ifdef DEBUG_NUBUS_INT
- printk("nubus_irq: map %x mask %x\n", map, nubus_active);
+#ifdef CONFIG_BLK_DEV_MAC_IDE
+ if (mac_ide_irq_p_hook)
+ ide_pending = mac_ide_irq_p_hook();
#endif
- if( (map = (map&nubus_active)) ==0 ) {
-#ifdef DEBUG_NUBUS_INT
- printk("nubus_irq: nothing pending, map %x mask %x\n",
- map, nubus_active);
+ if ( (map = (allints&nubus_active)) == 0
+#ifdef CONFIG_BLK_DEV_MAC_IDE
+ && !ide_pending
#endif
- nubus_irqs[7]++;
+ )
+ {
+ if (ct == 0) {
+#ifdef DEBUG_VIA_NUBUS
+ if (console_loglevel > 5)
+ printk("nubus_irq: nothing pending, map %x mask %x active %x\n",
+ allints, nubus_active, map);
+#endif
+ nubus_irqs[7]++;
+ }
+ /* clear it */
+ if (allints)
+ if (via2_is_rbv)
+ via_write(rbv_regp, rIFR, 0x02);
+ else
+ via_write(via2_regp, vIFR, 0x02);
break;
}
+#ifdef DEBUG_VIA_NUBUS
+ if (console_loglevel > 6)
+ printk("nubus_irq: map %x mask %x active %x\n",
+ allints, nubus_active, map);
+#endif
+
+#ifdef CONFIG_BLK_DEV_MAC_IDE
+ if (mac_ide_intr_hook && ide_pending) {
+ mac_ide_intr_hook(IRQ_MAC_NUBUS, via, regs);
+ mac_ide_irqs++;
+ }
+#endif
+
if(ct++>2)
{
-#ifdef DEBUG_NUBUS_INT
- printk("nubus stuck events - %d/%d\n", map, nubus_active);
-#endif
+ if (console_loglevel > 5)
+ printk("nubus stuck events - %x/%x/%x ide %x\n",
+ allints, nubus_active, map, ide_pending);
+ nubus_stuck_events++;
+
return;
}
@@ -1583,12 +1672,14 @@
printk("nubus_irq: map %x mask %x\n", map, nubus_active);
#endif
if( (map = (map&nubus_active)) ==0 ) {
+ if (ct == 0) {
#ifdef CONFIG_BLK_DEV_MAC_IDE
- if (!mac_ide_intr_hook)
- printk("nubus_irq: nothing pending, map %x mask %x\n",
- map, nubus_active);
+ if (!mac_ide_intr_hook)
+ printk("nubus_irq: nothing pending, map %x mask %x\n",
+ map, nubus_active);
#endif
- nubus_irqs[7]++;
+ nubus_irqs[7]++;
+ }
break;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov