5 * In contrary to the Amiga and Atari platforms, the Mac hardware seems to
6 * exclusively use the autovector interrupts (the 'generic level0-level7'
7 * interrupts with exception vectors 0x19-0x1f). The following interrupt levels
10 * - slot 0: one second interrupt
12 * - slot 2: ADB data ready (SR full)
13 * - slot 3: ADB data (CB2)
14 * - slot 4: ADB clock (CB1)
17 * - slot 7: status of IRQ; signals 'any enabled int.'
19 * 2 - VIA2, RBV or OSS
25 * - subdivided into Channel B and Channel A interrupts
31 * AV Macs only, handled by PSC:
33 * 3 - MACE ethernet IRQ (DMA complete on level 4)
37 * Using the autovector irq numbers for Linux/m68k hardware interrupts without
38 * the IRQ_MACHSPEC bit set would interfere with the general m68k interrupt
39 * handling in kernel versions 2.0.x, so the following strategy is used:
41 * - mac_init_IRQ installs the low-level entry points for the via1 and via2
42 * exception vectors and the corresponding handlers (C functions); these
43 * entry points just add the machspec bit and call the handlers proper.
44 * (in principle, the C functions can be installed as the exception vectors
45 * directly, as they are hardcoded anyway; that's the current method).
47 * - via[12]_irq determine what interrupt sources have triggered the interrupt,
48 * and call the corresponding device interrupt handlers.
49 * (currently, via1_irq and via2_irq just call via_irq, passing the via base
50 * address. RBV interrupts are handled by (you guessed it) rbv_irq).
51 * Some interrupt functions want to have the interrupt number passed, so
52 * via_irq and rbv_irq need to generate the 'fake' numbers from scratch.
54 * - for the request/free/enable/disable business, interrupt sources are
55 * numbered internally (suggestion: keep irq 0-7 unused :-). One bit in the
56 * irq number specifies the via# to use, i.e. via1 interrupts are 8-16,
57 * via2 interrupts 17-32, rbv interrupts ...
58 * The device interrupt table and the irq_enable bitmap is maintained by
59 * the machspec interrupt code; all device drivers should only use these
62 * - For future porting to version 2.1 (and removing of the machspec bit) it
63 * should be sufficient to use the same numbers (everything > 7 is assumed
64 * to be machspec, according to Jes!).
67 * - integrate Nubus interrupts in request/free_irq
72 #include <linux/config.h>
73 #include <linux/types.h>
74 #include <linux/kernel.h>
75 #include <linux/sched.h>
76 #include <linux/kernel_stat.h>
77 #include <linux/interrupt.h> /* for intr_count */
78 #include <linux/delay.h>
80 #include <asm/system.h>
82 #include <asm/traps.h>
83 #include <asm/machw.h>
84 #include <asm/macintosh.h>
87 #include <asm/macints.h>
90 * Interrupt handler and parameter types
93 void (*handler
)(int, void *, struct pt_regs
*);
103 unsigned int disabled
;
104 unsigned int pending
;
108 * Array with irq's and their parameter data.
110 static struct irqhandler via1_handler
[8];
111 static struct irqhandler via2_handler
[8];
112 static struct irqhandler rbv_handler
[8];
113 static struct irqhandler psc3_handler
[8];
114 static struct irqhandler scc_handler
[8];
115 static struct irqhandler psc5_handler
[8];
116 static struct irqhandler psc6_handler
[8];
117 static struct irqhandler nubus_handler
[8];
119 static struct irqhandler
*handler_table
[8];
122 * This array hold the rest of parameters of int handlers: type
123 * (slow,fast,prio) and the name of the handler. These values are only
126 static struct irqparam via1_param
[8];
127 static struct irqparam via2_param
[8];
128 static struct irqparam rbv_param
[8];
129 static struct irqparam psc3_param
[8];
130 static struct irqparam scc_param
[8];
131 static struct irqparam psc5_param
[8];
132 static struct irqparam psc6_param
[8];
133 static struct irqparam nubus_param
[8];
135 static struct irqparam
*param_table
[8];
138 * This array holds the 'disabled' and 'pending' software flags maintained
139 * by mac_{enable,disable}_irq and the generic via_irq function.
142 static struct irqflags irq_flags
[8];
145 * This array holds the pointers to the various VIA or other interrupt
146 * controllers, indexed by interrupt level
149 static volatile unsigned char *via_table
[8];
152 * Arrays with irq statistics
154 static unsigned long via1_irqs
[8];
155 static unsigned long via2_irqs
[8];
156 static unsigned long rbv_irqs
[8];
157 static unsigned long psc3_irqs
[8];
158 static unsigned long scc_irqs
[8];
159 static unsigned long psc5_irqs
[8];
160 static unsigned long psc6_irqs
[8];
161 static unsigned long nubus_irqs
[8];
163 static unsigned long *mac_irqs
[8];
166 * VIA2 / RBV register base pointers
169 volatile unsigned char *via2_regp
=(volatile unsigned char *)VIA2_BAS
;
170 volatile unsigned char *rbv_regp
=(volatile unsigned char *)VIA2_BAS_IIci
;
171 volatile unsigned char *oss_regp
=(volatile unsigned char *)OSS_BAS
;
172 volatile unsigned char *psc_regp
=(volatile unsigned char *)PSC_BAS
;
175 * Flags to control via2 / rbv behaviour
178 static int via2_is_rbv
= 0;
179 static int via2_is_oss
= 0;
180 static int rbv_clear
= 0;
182 /* fake VIA2 to OSS bit mapping */
183 static int oss_map
[8] = {2, 7, 0, 1, 3, 4, 5};
185 void oss_irq(int irq
, void *dev_id
, struct pt_regs
*regs
);
186 static void oss_do_nubus(int irq
, void *dev_id
, struct pt_regs
*regs
);
189 void psc_irq(int irq
, void *dev_id
, struct pt_regs
*regs
);
195 extern void psc_init(void);
198 * console_loglevel determines NMI handler function
201 extern int console_loglevel
;
206 extern int in_keybinit
;
207 void adb_queue_poll(void);
209 /* Defined in entry.S; only increments 'num_spurious' */
210 asmlinkage
void bad_interrupt(void);
212 void nubus_wtf(int slot
, void *via
, struct pt_regs
*regs
);
214 void mac_nmi_handler(int irq
, void *dev_id
, struct pt_regs
*regs
);
215 void mac_debug_handler(int irq
, void *dev_id
, struct pt_regs
*regs
);
217 static void via_do_nubus(int slot
, void *via
, struct pt_regs
*regs
);
219 /*#define DEBUG_VIA*/
221 void mac_init_IRQ(void)
226 printk("Mac interrupt stuff initializing ...\n");
229 via2_regp
= (unsigned char *)VIA2_BAS
;
230 rbv_regp
= (unsigned char *)VIA2_BAS_IIci
;
232 /* initialize the hardwired (primary, autovector) IRQs */
234 /* level 1 IRQ: VIA1, always present */
235 sys_request_irq(1, via1_irq
, IRQ_FLG_LOCK
, "via1", via1_irq
);
238 if (macintosh_config
->via_type
== MAC_VIA_IIci
) {
240 * A word of caution: the definitions here only affect interrupt
241 * handling, see via6522.c for yet another file to change
242 * base addresses and RBV flags
245 /* yes, this is messy - the IIfx deserves a class of his own */
246 if (macintosh_config
->ident
== MAC_MODEL_IIFX
) {
247 /* no real VIA2, the OSS seems _very_different */
249 /* IIfx has OSS, at a different base address than RBV */
250 rbv_regp
= (unsigned char *) OSS_BAS
;
251 sys_request_irq(2, oss_irq
, IRQ_FLG_LOCK
, "oss", oss_irq
);
253 /* VIA2 is part of the RBV: different base, other offsets */
256 /* LC III weirdness: IFR seems to behave like VIA2 */
257 /* FIXME: maybe also for LC II ?? */
258 if (macintosh_config
->ident
== MAC_MODEL_LCIII
) {
263 /* level 2 IRQ: RBV/OSS; we only care about RBV for now */
264 sys_request_irq(2, rbv_irq
, IRQ_FLG_LOCK
, "rbv", rbv_irq
);
267 /* level 2 IRQ: VIA2 */
268 sys_request_irq(2, via2_irq
, IRQ_FLG_LOCK
, "via2", via2_irq
);
271 * level 4 IRQ: SCC - use 'master' interrupt routine that calls the
272 * registered channel-specific interrupts in turn.
273 * Currently, one interrupt per channel is used, solely
274 * to pass the correct async_info as parameter!
276 #if 0 /* want to install debug/SCC shutup routine until SCC init */
277 sys_request_irq(4, mac_SCC_handler
, IRQ_FLG_STD
, "INT4", mac_SCC_handler
);
279 sys_request_irq(4, mac_debug_handler
, IRQ_FLG_STD
, "INT4", mac_debug_handler
);
281 /* Alan uses IRQ 5 for SCC ?? */
282 sys_request_irq(5, mac_debug_handler
, IRQ_FLG_STD
, "INT5", mac_debug_handler
);
285 sys_request_irq(6, mac_bang
, IRQ_FLG_LOCK
, "offswitch", mac_bang
);
287 /* level 7 (or NMI) : debug stuff */
288 sys_request_irq(7, mac_nmi_handler
, IRQ_FLG_STD
, "NMI", mac_nmi_handler
);
290 /* initialize the handler tables for VIAs */
291 for (i
= 0; i
< 8; i
++) {
292 via1_handler
[i
].handler
= mac_default_handler
;
293 via1_handler
[i
].dev_id
= NULL
;
294 via1_param
[i
].flags
= IRQ_FLG_STD
;
295 via1_param
[i
].devname
= NULL
;
297 via2_handler
[i
].handler
= mac_default_handler
;
298 via2_handler
[i
].dev_id
= NULL
;
299 via2_param
[i
].flags
= IRQ_FLG_STD
;
300 via2_param
[i
].devname
= NULL
;
302 rbv_handler
[i
].handler
= mac_default_handler
;
303 rbv_handler
[i
].dev_id
= NULL
;
304 rbv_param
[i
].flags
= IRQ_FLG_STD
;
305 rbv_param
[i
].devname
= NULL
;
307 scc_handler
[i
].handler
= mac_default_handler
;
308 scc_handler
[i
].dev_id
= NULL
;
309 scc_param
[i
].flags
= IRQ_FLG_STD
;
310 scc_param
[i
].devname
= NULL
;
312 /* NUBUS interrupts routed through VIA2 slot 2 - special */
313 nubus_handler
[i
].handler
= nubus_wtf
;
314 nubus_handler
[i
].dev_id
= NULL
;
315 nubus_param
[i
].flags
= IRQ_FLG_STD
;
316 nubus_param
[i
].devname
= NULL
;
320 /* initialize the handler tables (level 1 -> via_handler[0] !!!) */
321 via_table
[0] = via1_regp
;
322 handler_table
[0] = &via1_handler
[0];
323 param_table
[0] = &via1_param
[0];
324 mac_irqs
[0] = &via1_irqs
[0];
326 if (via2_is_rbv
|| via2_is_oss
) {
327 via_table
[1] = rbv_regp
;
328 handler_table
[1] = &rbv_handler
[0];
329 param_table
[1] = &rbv_param
[0];
330 mac_irqs
[1] = &rbv_irqs
[0];
332 via_table
[1] = via2_regp
;
333 handler_table
[1] = &via2_handler
[0];
334 param_table
[1] = &via2_param
[0];
335 mac_irqs
[1] = &via2_irqs
[0];
340 handler_table
[2] = &rbv_handler
[0];
341 handler_table
[3] = &scc_handler
[0];
342 handler_table
[4] = NULL
;
343 handler_table
[5] = NULL
;
344 handler_table
[6] = NULL
;
345 handler_table
[7] = &nubus_handler
[0];
347 param_table
[2] = &rbv_param
[0];
348 param_table
[3] = &scc_param
[0];
349 param_table
[7] = &nubus_param
[0];
351 mac_irqs
[2] = &rbv_irqs
[0];
352 mac_irqs
[3] = &scc_irqs
[0];
353 mac_irqs
[7] = &nubus_irqs
[0];
356 * AV Macs: shutup the PSC ints
358 if (macintosh_config
->ident
== MAC_MODEL_C660
359 || macintosh_config
->ident
== MAC_MODEL_Q840
) {
362 handler_table
[2] = &psc3_handler
[0];
363 /* handler_table[3] = &psc4_handler[0]; */
364 handler_table
[4] = &psc5_handler
[0];
365 handler_table
[5] = &psc6_handler
[0];
367 param_table
[2] = &psc3_param
[0];
368 /* param_table[3] = &psc4_param[0]; */
369 param_table
[4] = &psc5_param
[0];
370 param_table
[5] = &psc6_param
[0];
372 mac_irqs
[2] = &psc3_irqs
[0];
373 /* mac_irqs[3] = &psc4_irqs[0]; */
374 mac_irqs
[4] = &psc5_irqs
[0];
375 mac_irqs
[5] = &psc6_irqs
[0];
377 sys_request_irq(3, psc_irq
, IRQ_FLG_STD
, "PSC3", psc_irq
);
378 sys_request_irq(4, psc_irq
, IRQ_FLG_STD
, "PSC4", psc_irq
);
379 sys_request_irq(5, psc_irq
, IRQ_FLG_STD
, "PSC5", psc_irq
);
380 sys_request_irq(6, psc_irq
, IRQ_FLG_STD
, "PSC6", psc_irq
);
384 printk("Mac interrupt init done!\n");
389 * We have no machine specific interrupts on a macintoy
390 * Yet, we need to register/unregister interrupts ... :-)
391 * Currently unimplemented: Test for valid irq number, chained irqs,
392 * Nubus interrupts (use nubus_request_irq!).
395 int mac_request_irq (unsigned int irq
, void (*handler
)(int, void *, struct pt_regs
*),
396 unsigned long flags
, const char *devname
, void *dev_id
)
398 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
399 int irqidx
= (irq
& IRQ_IDX_MASK
);
400 struct irqhandler
*via_handler
;
401 struct irqparam
*via_param
;
402 volatile unsigned char *via
;
405 printk ("%s: IRQ %d on VIA%d[%d] requested from %s\n",
406 __FUNCTION__
, irq
, srcidx
+1, irqidx
, devname
);
409 if (flags
< IRQ_TYPE_SLOW
|| flags
> IRQ_TYPE_PRIO
) {
410 printk ("%s: Bad irq type %ld requested from %s\n",
411 __FUNCTION__
, flags
, devname
);
415 /* figure out what VIA is handling this irq */
416 if (irq
< IRQ_IDX(IRQ_VIA1_1
) || irq
>= IRQ_IDX(IRQ_NUBUS_1
)) {
417 /* non-via irqs unimplemented */
418 printk ("%s: Bad irq source %d on VIA %d requested from %s\n",
419 __FUNCTION__
, irq
, srcidx
, devname
);
423 /* figure out if SCC pseudo-irq (redundant ??) */
424 if (irq
>= IRQ_IDX(IRQ_SCC
) && irq
< IRQ_IDX(IRQ_PSC5_0
)) {
425 /* set specific SCC handler */
426 scc_handler
[irqidx
].handler
= handler
;
427 scc_handler
[irqidx
].dev_id
= dev_id
;
428 scc_param
[irqidx
].flags
= flags
;
429 scc_param
[irqidx
].devname
= devname
;
434 /* add similar hack for Nubus pseudo-irq here - hide nubus_request_irq */
436 via
= (volatile unsigned char *) via_table
[srcidx
];
440 via_handler
= handler_table
[srcidx
];
441 via_param
= param_table
[srcidx
];
443 /* check for conflicts or possible replacement */
445 /* set the handler - no chained irqs yet !! */
446 via_handler
[irqidx
].handler
= handler
;
447 via_handler
[irqidx
].dev_id
= dev_id
;
448 via_param
[irqidx
].flags
= flags
;
449 via_param
[irqidx
].devname
= devname
;
451 /* and turn it on ... careful, that's VIA only ... */
452 if (srcidx
== SRC_VIA2
&& via2_is_rbv
)
453 via_write(via
, rIER
, via_read(via
, rIER
)|0x80|(1<<(irqidx
)));
454 else if (srcidx
== SRC_VIA2
&& via2_is_oss
)
455 via_write(oss_regp
, oss_map
[irqidx
]+8, 2);
457 via_write(via
, vIER
, via_read(via
, vIER
)|0x80|(1<<(irqidx
)));
460 if (irq
== IRQ_IDX(IRQ_MAC_SCSI
)) {
462 * Set vPCR for SCSI interrupts. (what about RBV here?)
463 * 980429 MS: RBV is ok, OSS seems to be differentt
466 /* CB2 (IRQ) indep. interrupt input, positive edge */
467 /* CA2 (DRQ) indep. interrupt input, positive edge */
468 via_write(via
, vPCR
, 0x66);
471 /* CB2 (IRQ) indep. interrupt input, negative edge */
472 /* CA2 (DRQ) indep. interrupt input, negative edge */
473 via_write(via
, vPCR
, 0x22);
480 void mac_free_irq (unsigned int irq
, void *dev_id
)
483 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
484 int irqidx
= (irq
& IRQ_IDX_MASK
);
485 struct irqhandler
*via_handler
;
486 struct irqparam
*via_param
;
487 volatile unsigned char *via
;
490 printk ("%s: IRQ %d on VIA%d[%d] freed\n",
491 __FUNCTION__
, irq
, srcidx
+1, irqidx
);
494 /* figure out what VIA is handling this irq */
495 if (irq
< IRQ_IDX(IRQ_VIA1_1
) || irq
>= IRQ_IDX(IRQ_NUBUS_1
)) {
496 /* non-via irqs unimplemented */
503 /* figure out if SCC pseudo-irq */
504 if (irq
>= IRQ_IDX(IRQ_SCC
) && irq
< IRQ_IDX(IRQ_PSC5_0
)) {
505 /* clear specific SCC handler */
506 scc_handler
[irqidx
].handler
= mac_default_handler
;
507 scc_handler
[irqidx
].dev_id
= NULL
;
508 scc_param
[irqidx
].flags
= IRQ_FLG_STD
;
509 scc_param
[irqidx
].devname
= NULL
;
511 restore_flags(flags
);
515 via
= (volatile unsigned char *) via_table
[srcidx
];
516 via_handler
= handler_table
[srcidx
];
517 via_param
= param_table
[srcidx
];
519 if ( !via
|| (via_handler
[irqidx
].dev_id
!= dev_id
) ) {
520 restore_flags(flags
);
524 /* clear the handler - no chained irqs yet !! */
525 via_handler
[irqidx
].handler
= mac_default_handler
;
526 via_handler
[irqidx
].dev_id
= NULL
;
527 via_param
[irqidx
].flags
= IRQ_FLG_STD
;
528 via_param
[irqidx
].devname
= NULL
;
530 /* and turn it off */
531 if (srcidx
== SRC_VIA2
&& via2_is_rbv
)
532 via_write(via
, rIER
, (via_read(via
, rIER
)&(1<<irqidx
)));
533 else if (srcidx
== SRC_VIA2
&& via2_is_oss
)
534 via_write(oss_regp
, oss_map
[irqidx
]+8, 0);
536 via_write(via
, vIER
, (via_read(via
, vIER
)&(1<<irqidx
)));
538 restore_flags(flags
);
542 printk("%s: tried to remove invalid irq\n", __FUNCTION__
);
548 * {en,dis}able_irq have the usual semantics of temporary blocking the
549 * interrupt, but not loosing requests that happen between disabling and
550 * enabling. On Atari, this is done with the MFP mask registers.
552 * On the Mac, this isn't possible: there is no VIA mask register.
553 * Needs to be implemented in software, setting 'mask' bits in a separate
554 * struct for each interrupt controller. These mask bits need to be checked
555 * by the VIA interrupt routine which should ignore requests for masked IRQs
556 * (after possibly ack'ing them).
558 * On second thought: some of the IRQ sources _can_ be turned off via bits
559 * in the VIA output registers. Need to check this ...
561 * TBI: According to the VIA docs, clearing a bit in the IER has the effect of
562 * blocking generation of the interrupt, but the internal interrupt condition
563 * is preserved. So the IER might be used as mask register here, and turnon_irq
564 * would need to clear the interrupt bit in the IFR to prevent getting an
567 * Implementation note: the irq no's here are the _machspec_ irqs, hence the
568 * hack with srcidx to figure out which VIA/RBV handles the interrupt.
569 * That's fundamentally different when it comes to the interrupt handlers
570 * proper: these get the interrupt level no. as argument, all information about
571 * which source triggered the int. is buried in the VIA IFR ... The int. level
572 * points us to the proper handler, so we could do a sanity check there ...
575 void mac_enable_irq (unsigned int irq
)
577 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
578 int irqidx
= (irq
& IRQ_IDX_MASK
);
580 irq_flags
[srcidx
].disabled
&= ~(1<<irqidx
);
582 * Call handler here if irq_flags[srcidx].pending & 1<<irqidx ??
583 * The structure of via_irq prevents this, sort of: it warns if
584 * no true events are pending. Maybe that's being changed ...
585 * Other problem: is it always possible to call an interrupt handler,
586 * or should that depend on the current interrupt level?
590 void mac_disable_irq (unsigned int irq
)
592 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
593 int irqidx
= (irq
& IRQ_IDX_MASK
);
595 irq_flags
[srcidx
].disabled
|= (1<<irqidx
);
599 * In opposite to {en,dis}able_irq, requests between turn{off,on}_irq are not
600 * "stored". This is done with the VIA interrupt enable register
603 void mac_turnon_irq( unsigned int irq
)
605 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
606 int irqidx
= (irq
& IRQ_IDX_MASK
);
607 volatile unsigned char *via
;
609 via
= (volatile unsigned char *) via_table
[srcidx
];
613 if (srcidx
== SRC_VIA2
&& via2_is_rbv
)
614 via_write(via
, rIER
, via_read(via
, rIER
)|0x80|(1<<(irqidx
)));
615 else if (srcidx
== SRC_VIA2
&& via2_is_oss
)
616 via_write(oss_regp
, oss_map
[irqidx
]+8, 2);
617 else if (srcidx
>= SRC_VIA2
)
618 via_write(via
, (0x104 + 0x10*srcidx
),
619 via_read(via
, (0x104 + 0x10*srcidx
))|0x80|(1<<(irqidx
)));
621 via_write(via
, vIER
, via_read(via
, vIER
)|0x80|(1<<(irqidx
)));
625 void mac_turnoff_irq( unsigned int irq
)
627 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
628 int irqidx
= (irq
& IRQ_IDX_MASK
);
629 volatile unsigned char *via
;
631 via
= (volatile unsigned char *) via_table
[srcidx
];
635 if (srcidx
== SRC_VIA2
&& via2_is_rbv
)
636 via_write(via
, rIER
, (via_read(via
, rIER
)&(1<<irqidx
)));
637 else if (srcidx
== SRC_VIA2
&& via2_is_oss
)
638 via_write(oss_regp
, oss_map
[irqidx
]+8, 0);
639 else if (srcidx
>= SRC_VIA2
)
640 via_write(via
, (0x104 + 0x10*srcidx
),
641 via_read(via
, (0x104 + 0x10*srcidx
))|(1<<(irqidx
)));
643 via_write(via
, vIER
, (via_read(via
, vIER
)&(1<<irqidx
)));
647 * These functions currently only handle the software-maintained irq pending
648 * list for disabled irqs - manipulating the actual irq flags in the via would
649 * require clearing single bits in the via, such as (probably)
650 * via_write(via, vIFR, (via_read(via, vIFR)&(1<<irqidx))); - don't know if
651 * this has side-effects ...
654 void mac_clear_pending_irq( unsigned int irq
)
656 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
657 int irqidx
= (irq
& IRQ_IDX_MASK
);
659 irq_flags
[srcidx
].pending
&= ~(1<<irqidx
);
662 int mac_irq_pending( unsigned int irq
)
665 volatile unsigned char *via
;
667 int srcidx
= ((irq
& IRQ_SRC_MASK
)>>3) - 1;
668 int irqidx
= (irq
& IRQ_IDX_MASK
);
670 pending
= irq_flags
[srcidx
].pending
& (1<<irqidx
);
672 via
= (volatile unsigned char *) via_table
[srcidx
];
676 if (srcidx
== SRC_VIA2
&& via2_is_rbv
)
677 pending
|= via_read(via
, rIFR
)&(1<<irqidx
);
678 else if (srcidx
== SRC_VIA2
&& via2_is_oss
)
679 pending
|= via_read(via
, oIFR
)&0x03&(1<<oss_map
[irqidx
]);
680 else if (srcidx
>= SRC_VIA2
)
681 pending
|= via_read(via
, (0x100 + 0x10*srcidx
))&(1<<irqidx
);
683 pending
|= via_read(via
, vIFR
)&(1<<irqidx
);
688 int mac_get_irq_list (char *buf
)
693 for (i
= VIA1_SOURCE_BASE
; i
< NUM_MAC_SOURCES
+8; ++i
) {
694 srcidx
= ((i
& IRQ_SRC_MASK
)>>3) - 1;
695 irqidx
= (i
& IRQ_IDX_MASK
);
701 if (mac_irqs
[srcidx
] == NULL
)
705 * never used by VIAs, unused by others so far, counts
706 * the magic 'nothing pending' cases ...
708 if (irqidx
== 7 && mac_irqs
[srcidx
][irqidx
]) {
709 len
+= sprintf(buf
+len
, "Level %01d: %10lu (spurious) \n",
711 mac_irqs
[srcidx
][irqidx
]);
716 * Nothing registered for this IPL: skip
719 if (handler_table
[srcidx
] == NULL
)
723 * No handler installed: skip
726 if (handler_table
[srcidx
][irqidx
].handler
== mac_default_handler
||
727 handler_table
[srcidx
][irqidx
].handler
== nubus_wtf
)
731 if (i
< VIA2_SOURCE_BASE
)
732 len
+= sprintf(buf
+len
, "via1 %01d: %10lu ",
734 mac_irqs
[srcidx
][irqidx
]);
735 else if (i
< RBV_SOURCE_BASE
)
736 len
+= sprintf(buf
+len
, "via2 %01d: %10lu ",
738 mac_irqs
[srcidx
][irqidx
]);
739 else if (i
< MAC_SCC_SOURCE_BASE
)
740 len
+= sprintf(buf
+len
, "rbv %01d: %10lu ",
742 mac_irqs
[srcidx
][irqidx
]);
743 else if (i
< NUBUS_SOURCE_BASE
)
744 len
+= sprintf(buf
+len
, "scc %01d: %10lu ",
746 mac_irqs
[srcidx
][irqidx
]);
748 len
+= sprintf(buf
+len
, "nubus %01d: %10lu ",
750 mac_irqs
[srcidx
][irqidx
]);
752 len
+= sprintf(buf
+len
, "%s\n",
753 param_table
[srcidx
][irqidx
].devname
);
757 len
+= sprintf(buf
+len
, "spurio.: %10u\n", num_spurious
);
761 void via_scsi_clear(void)
763 volatile unsigned char deep_magic
;
765 via_write(rbv_regp
, rIFR
, (1<<3)|(1<<0)|0x80);
766 deep_magic
= via_read(rbv_regp
, rBufB
);
767 } else if (via2_is_oss
) {
769 /* via_write(oss_regp, 9, 0) */;
771 deep_magic
= via_read(via2_regp
, vBufB
);
772 mac_enable_irq( IRQ_IDX(IRQ_MAC_SCSI
) );
776 void mac_default_handler(int irq
, void *dev_id
, struct pt_regs
*regs
)
779 printk("Unexpected IRQ %d\n", irq
);
783 static int num_debug
[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
785 void mac_debug_handler(int irq
, void *dev_id
, struct pt_regs
*regs
)
787 if (num_debug
[irq
] < 10) {
788 printk("DEBUG: Unexpected IRQ %d\n", irq
);
793 void scsi_mac_debug(void);
794 void scsi_mac_polled(void);
796 static int in_nmi
= 0;
797 static volatile int nmi_hold
= 0;
799 void mac_nmi_handler(int irq
, void *dev_id
, struct pt_regs
*fp
)
803 * generate debug output on NMI switch if 'debug' kernel option given
804 * (only works with Penguin!)
810 printk("PC: %08lx\nSR: %04x SP: %p\n", fp
->pc
, fp
->sr
, fp
);
812 for (i
=0; i
<100; i
++)
817 printk("... pausing, press NMI to resume ...");
825 while (nmi_hold
== 1)
832 if ( console_loglevel
>= 8 ) {
835 printk("PC: %08lx\nSR: %04x SP: %p\n", fp
->pc
, fp
->sr
, fp
);
836 printk("d0: %08lx d1: %08lx d2: %08lx d3: %08lx\n",
837 fp
->d0
, fp
->d1
, fp
->d2
, fp
->d3
);
838 printk("d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
839 fp
->d4
, fp
->d5
, fp
->a0
, fp
->a1
);
841 if (STACK_MAGIC
!= *(unsigned long *)current
->kernel_stack_page
)
842 printk("Corrupted stack page\n");
843 printk("Process %s (pid: %d, stackpage=%08lx)\n",
844 current
->comm
, current
->pid
, current
->kernel_stack_page
);
846 dump_stack((struct frame
*)fp
);
848 /* printk("NMI "); */
855 * The generic VIA interrupt routines (shamelessly stolen from Alan Cox's
856 * via6522.c :-), disable/pending masks added.
857 * The int *viaidx etc. is just to keep the prototype happy ...
860 static void via_irq(unsigned char *via
, int *viaidx
, struct pt_regs
*regs
)
862 unsigned char events
=(via_read(via
, vIFR
)&via_read(via
,vIER
))&0x7F;
865 struct irqhandler
*via_handler
= handler_table
[*viaidx
];
866 struct irqparam
*via_param
= param_table
[*viaidx
];
867 unsigned long *via_irqs
= mac_irqs
[*viaidx
];
869 /* to be changed, possibly: for each non'masked', enabled IRQ, read
870 * flag bit, ack and call handler ...
871 * Currently: all pending irqs ack'ed en bloc.
872 * If ack for masked IRQ required: keep 'pending' info separate.
875 /* shouldn't we disable interrupts here ?? */
885 /* should go away; mostly missing timer ticks and ADB events */
886 printk("via%d_irq: nothing pending, flags %x mask %x!\n",
887 *viaidx
+ 1, via_read(via
, vIFR
), via_read(via
,vIER
));
895 * limited verbosity for VIA interrupts
898 if ( (*viaidx
== 0 && events
!= 1<<6) /* timer int */
899 || (*viaidx
== 1 && events
!= 1<<3) ) /* SCSI IRQ */
901 if ( *viaidx
== 0 && (events
& 1<<2) )
903 printk("via_irq: irq %d events %x !\n", (*viaidx
)+1, events
);
908 * Clear the pending flag
911 via_write(via
, vIFR
, events
);
914 * Now see what bits are raised
919 /* determine machspec. irq no. */
920 int irq
= ((*viaidx
)+1)* 8 + i
;
921 /* call corresponding handlers */
923 if (irq_flags
[*viaidx
].disabled
& (1<<i
)) {
924 if (!irq_flags
[*viaidx
].pending
&(1<<i
))
926 /* irq disabled -> mark pending */
927 irq_flags
[*viaidx
].pending
|= (1<<i
);
930 /* irq enabled -> call handler */
931 (via_handler
[i
].handler
)(irq
, via
, regs
);
934 /* and call handlers for pending irqs - first ?? */
935 if ( (irq_flags
[*viaidx
].pending
& (1<<i
))
936 && !(irq_flags
[*viaidx
].disabled
& (1<<i
)) ) {
937 /* call handler for re-enabled irq */
938 (via_handler
[i
].handler
)(irq
, via
, regs
);
939 /* and clear pending flag :-) */
940 irq_flags
[*viaidx
].pending
&= ~(1<<i
);
945 * And done ... check for more punishment!
948 events
=(via_read(via
, vIFR
)&via_read(via
,vIER
))&0x7F;
953 printk("via%d: stuck events %x\n", (*viaidx
)+1, events
);
965 * Caution: the following stuff is called from process_int as _autovector_
966 * system interrupts. So irq is always in the range 0-7 :-( and the selection
967 * of the appropriate VIA is up to the irq handler here based on the autovec
968 * irq number. There's no information whatsoever about which source on the VIA
969 * triggered the int - and that's what the machspec irq no's are about.
970 * Broken design :-((((
977 void via1_irq(int irq
, void *dev_id
, struct pt_regs
*regs
)
979 int srcidx
= IRQ_IDX(irq
) - 1;
980 via_irq((unsigned char *)via1_regp
, &srcidx
, regs
);
985 * Nubus / SCSI interrupts, VIA style (could be wrapped into via1_irq or
986 * via_irq directly by selecting the regp based on the irq!)
989 void via2_irq(int irq
, void *dev_id
, struct pt_regs
*regs
)
991 int srcidx
= IRQ_IDX(irq
) - 1;
992 via_irq((unsigned char *)via2_regp
, &srcidx
, regs
);
996 * Nubus / SCSI interrupts; RBV style
997 * The RBV is different. RBV appears to stand for randomly broken
998 * VIA (or even real broken VIA).
1001 void rbv_irq(int irq
, void *dev_id
, struct pt_regs
*regs
)
1003 int srcidx
= IRQ_IDX(irq
) - 1; /* MUST be 1 !! */
1004 volatile unsigned char *via
= rbv_regp
;
1005 unsigned char events
=(via_read(via
, rIFR
)&via_read(via
,rIER
))&0x7F;
1008 struct irqhandler
*via_handler
= handler_table
[srcidx
];
1009 struct irqparam
*via_param
= param_table
[srcidx
];
1011 /* shouldn't we disable interrupts here ?? */
1021 printk("rbv_irq: nothing pending, flags %x mask %x!\n",
1022 via_read(via
, rIFR
), via_read(via
,rIER
));
1030 * limited verbosity for RBV interrupts (add more if needed)
1032 if ( srcidx
== 1 && events
!= 1<<3 ) /* SCSI IRQ */
1033 printk("rbv_irq: irq %d (%d) events %x !\n", irq
, srcidx
+1, events
);
1036 /* to be changed, possibly: for each non'masked', enabled IRQ, read
1037 * flag bit, ack and call handler ...
1038 * Currently: all pending irqs ack'ed en bloc.
1039 * If ack for masked IRQ required: keep 'pending' info separate.
1044 * Clear the pending flag
1047 via_write(via
, rIFR
, events
| rbv_clear
);
1050 * Now see what bits are raised
1055 /* determine machspec. irq no. */
1056 int irq
= (srcidx
+1)* 8 + i
;
1057 /* call corresponding handlers */
1058 if (events
&(1<<i
)) {
1059 if (irq_flags
[srcidx
].disabled
& (1<<i
)) {
1060 if (!irq_flags
[srcidx
].pending
&(1<<i
))
1062 /* irq disabled -> mark pending */
1063 irq_flags
[srcidx
].pending
|= (1<<i
);
1066 /* irq enabled -> call handler */
1067 (via_handler
[i
].handler
)(irq
, via
, regs
);
1070 /* and call handlers for pending irqs - first ?? */
1071 if ( (irq_flags
[srcidx
].pending
& (1<<i
))
1072 && !(irq_flags
[srcidx
].disabled
& (1<<i
)) ) {
1073 /* call handler for re-enabled irq */
1074 (via_handler
[i
].handler
)(irq
, via
, regs
);
1075 /* and clear pending flag :-) */
1076 irq_flags
[srcidx
].pending
&= ~(1<<i
);
1081 * And done ... check for more punishment!
1084 events
=(via_read(via
, rIFR
)&via_read(via
,rIER
))&0x7F;
1088 printk("rbv: stuck events %x\n",events
);
1093 printk("rbv - bashing source %d\n",
1095 via_write(via
, rIER
, 1<<i
);
1096 via_write(via
, rIFR
, (1<<i
) | rbv_clear
);
1109 * Unexpected via interrupt
1112 void via_wtf(int slot
, void *via
, struct pt_regs
*regs
)
1115 printk("Unexpected event %d on via %p\n",slot
,via
);
1120 * Nubus / SCSI interrupts; OSS style
1121 * The OSS is even more different than the RBV. OSS appears to stand for
1122 * Obscenely Screwed Silicon ...
1124 * Latest NetBSD sources suggest the OSS should behave like a RBV, but
1125 * that's probably true for the 0x203 offset (Nubus/ADB-SWIM IOP) at best
1128 void oss_irq(int irq
, void *dev_id
, struct pt_regs
*regs
)
1130 int srcidx
= IRQ_IDX(irq
) - 1; /* MUST be 1 !! */
1131 volatile unsigned char *via
= oss_regp
;
1132 unsigned char events
=(via_read(via
, oIFR
))&0x03;
1133 unsigned char nub_ev
=(via_read(via
, nIFR
))&0x4F;
1134 unsigned char adb_ev
;
1137 struct irqhandler
*via_handler
= handler_table
[srcidx
];
1138 struct irqparam
*via_param
= param_table
[srcidx
];
1140 /* shouldn't we disable interrupts here ?? */
1142 adb_ev
= nub_ev
& 0x40;
1149 if (events
==0 && adb_ev
==0 && nub_ev
==0)
1151 printk("oss_irq: nothing pending, flags %x %x!\n",
1152 via_read(via
, oIFR
), via_read(via
, nIFR
));
1159 * limited verbosity for RBV interrupts (add more if needed)
1161 if ( events
!= 1<<3 ) /* SCSI IRQ */
1162 printk("oss_irq: irq %d events %x %x %x !\n", irq
, srcidx
+1,
1163 events
, adb_ev
, nub_ev
);
1167 * OSS priorities: call ADB handler first if registered, other events,
1169 * ADB: yet to be implemented!
1173 * ADB: try to shutup the IOP
1176 printk("Hands off ! Don't press this button ever again !!!\n");
1177 via_write(via
, 6, 0);
1182 * Clear the pending flags
1183 * How exactly is that supposed to work ??
1187 * Now see what bits are raised
1192 /* HACK HACK: map to bit number in OSS register */
1193 int irqidx
= oss_map
[i
];
1194 /* determine machspec. irq no. */
1195 int irq
= (srcidx
+1)* 8 + i
;
1196 /* call corresponding handlers */
1197 if ( (events
&(1<<irqidx
)) && /* bit set*/
1198 (via_read(via
, irqidx
+8)&0x7) ) { /* irq enabled */
1199 if (irq_flags
[srcidx
].disabled
& (1<<i
)) {
1200 if (!irq_flags
[srcidx
].pending
&(1<<i
))
1202 /* irq disabled -> mark pending */
1203 irq_flags
[srcidx
].pending
|= (1<<i
);
1206 /* irq enabled -> call handler */
1207 (via_handler
[i
].handler
)(irq
, via
, regs
);
1210 /* and call handlers for pending irqs - first ?? */
1211 if ( (irq_flags
[srcidx
].pending
& (1<<i
))
1212 && !(irq_flags
[srcidx
].disabled
& (1<<i
)) ) {
1213 /* call handler for re-enabled irq */
1214 (via_handler
[i
].handler
)(irq
, via
, regs
);
1215 /* and clear pending flag :-) */
1216 irq_flags
[srcidx
].pending
&= ~(1<<i
);
1221 * And done ... check for more punishment!
1224 events
=(via_read(via
, oIFR
)/*&via_read(via,rIER)*/)&0x03;
1228 printk("oss: stuck events %x\n",events
);
1233 printk("oss - bashing source %d\n",
1235 /* that should disable it */
1236 via_write(via
, 8+i
, 0);
1248 oss_do_nubus(irq
, via
, regs
);
1253 * Unexpected slot interrupt
1256 void nubus_wtf(int slot
, void *via
, struct pt_regs
*regs
)
1258 #ifdef DEBUG_VIA_NUBUS
1259 printk("Unexpected interrupt on nubus slot %d\n",slot
);
1264 * SCC master interrupt handler; sole purpose: pass the registered
1265 * async struct to the SCC handler proper.
1268 void mac_SCC_handler(int irq
, void *dev_id
, struct pt_regs
*regs
)
1271 /* 1+2: compatibility with PSC ! */
1272 for (i
= 1; i
< 3; i
++) /* currently only these two used */
1273 if (scc_handler
[i
].handler
!= mac_default_handler
)
1274 (scc_handler
[i
].handler
)(i
, scc_handler
[i
].dev_id
, regs
);
1279 * PSC interrupt handler
1282 void psc_irq(int irq
, void *dev_id
, struct pt_regs
*regs
)
1284 int srcidx
= IRQ_IDX(irq
) - 1;
1285 volatile unsigned char *via
= psc_regp
;
1286 unsigned int pIFR
= 0x100 + 0x10*srcidx
;
1287 unsigned int pIER
= 0x104 + 0x10*srcidx
;
1288 unsigned char events
=(via_read(via
, pIFR
)&via_read(via
,pIER
))&0xF;
1291 struct irqhandler
*via_handler
= handler_table
[srcidx
];
1292 struct irqparam
*via_param
= param_table
[srcidx
];
1294 /* shouldn't we disable interrupts here ?? */
1304 printk("rbv_irq: nothing pending, flags %x mask %x!\n",
1305 via_read(via
, pIFR
), via_read(via
,pIER
));
1307 mac_irqs
[srcidx
][7]++;
1313 * limited verbosity for RBV interrupts (add more if needed)
1315 if ( srcidx
== 1 && events
!= 1<<3 && events
!= 1<<1 ) /* SCSI IRQ */
1316 printk("psc_irq: irq %d events %x !\n", irq
, srcidx
+1, events
);
1319 /* to be changed, possibly: for each non'masked', enabled IRQ, read
1320 * flag bit, ack and call handler ...
1321 * Currently: all pending irqs ack'ed en bloc.
1322 * If ack for masked IRQ required: keep 'pending' info separate.
1327 * Clear the pending flag
1330 /* via_write(via, pIFR, events); */
1333 * Now see what bits are raised
1338 /* determine machspec. irq no. */
1339 int irq
= (srcidx
+1)* 8 + i
;
1340 /* call corresponding handlers */
1341 if (events
&(1<<i
)) {
1342 if (irq_flags
[srcidx
].disabled
& (1<<i
)) {
1343 if (!irq_flags
[srcidx
].pending
&(1<<i
))
1344 mac_irqs
[srcidx
][i
]++;
1345 /* irq disabled -> mark pending */
1346 irq_flags
[srcidx
].pending
|= (1<<i
);
1348 mac_irqs
[srcidx
][i
]++;
1349 /* irq enabled -> call handler */
1350 (via_handler
[i
].handler
)(irq
, via
, regs
);
1353 /* and call handlers for pending irqs - first ?? */
1354 if ( (irq_flags
[srcidx
].pending
& (1<<i
))
1355 && !(irq_flags
[srcidx
].disabled
& (1<<i
)) ) {
1356 /* call handler for re-enabled irq */
1357 (via_handler
[i
].handler
)(irq
, via
, regs
);
1358 /* and clear pending flag :-) */
1359 irq_flags
[srcidx
].pending
&= ~(1<<i
);
1364 * And done ... check for more punishment!
1367 events
=(via_read(via
,pIFR
)&via_read(via
,pIER
))&0x7F;
1371 printk("psc: stuck events %x\n",events
);
1376 printk("psc - bashing source %d\n",
1378 via_write(via
, pIER
, 1<<i
);
1379 /* via_write(via, pIFR, (1<<i)); */
1391 * Caution: slot numbers are currently 'hardcoded' to the range 9-15!
1392 * In general, the same request_irq() functions as above can be used if
1393 * the interrupt numbers specifed in macints.h are used.
1396 static int nubus_active
=0;
1398 int nubus_request_irq(int slot
, void *dev_id
, void (*handler
)(int,void *,struct pt_regs
*))
1401 /* printk("Nubus request irq for slot %d\n",slot);*/
1402 if(nubus_handler
[slot
].handler
!=nubus_wtf
)
1404 nubus_handler
[slot
].handler
=handler
;
1405 nubus_handler
[slot
].dev_id
=dev_id
;
1406 nubus_param
[slot
].flags
= IRQ_FLG_LOCK
;
1407 nubus_param
[slot
].devname
= "nubus slot";
1410 * if no nubus int. was active previously: register the main nubus irq
1414 if (!nubus_active
&& !via2_is_oss
) {
1415 request_irq(IRQ_MAC_NUBUS
, via_do_nubus
, IRQ_FLG_LOCK
,
1416 "nubus dispatch", via_do_nubus
);
1419 nubus_active
|=1<<slot
;
1420 /* printk("program slot %d\n",slot);*/
1421 /* printk("via2=%p\n",via2);*/
1423 via_write(via2
, vDirA
,
1424 via_read(via2
, vDirA
)|(1<<slot
));
1425 via_write(via2
, vBufA
, 0);
1428 via_write(oss_regp
, slot
, 2);
1429 else if (!via2_is_rbv
) {
1430 /* Make sure the bit is an input */
1431 via_write(via2_regp
, vDirA
,
1432 via_read(via2_regp
, vDirA
)&~(1<<slot
));
1434 /* printk("nubus irq on\n");*/
1438 int nubus_free_irq(int slot
)
1441 nubus_active
&=~(1<<slot
);
1442 nubus_handler
[slot
].handler
=nubus_wtf
;
1443 nubus_handler
[slot
].dev_id
= NULL
;
1444 nubus_param
[slot
].flags
= IRQ_FLG_STD
;
1445 nubus_param
[slot
].devname
= NULL
;
1448 via_write(rbv_regp
, rBufA
, 1<<slot
);
1449 else if (via2_is_oss
)
1450 via_write(oss_regp
, slot
, 0);
1452 via_write(via2_regp
, vDirA
,
1453 via_read(via2_regp
, vDirA
)|(1<<slot
));
1454 via_write(via2_regp
, vBufA
, 1<<slot
);
1455 via_write(via2_regp
, vDirA
,
1456 via_read(via2_regp
, vDirA
)&~(1<<slot
));
1461 #ifdef CONFIG_BLK_DEV_MAC_IDE
1463 * IDE interrupt hook
1465 extern void (*mac_ide_intr_hook
)(int, void *, struct pt_regs
*);
1469 * Nubus dispatch handler - VIA/RBV style
1471 static void via_do_nubus(int slot
, void *via
, struct pt_regs
*regs
)
1477 /* printk("nubus interrupt\n");*/
1479 /* lock the nubus interrupt */
1481 via_write(rbv_regp
, rIFR
, 0x82);
1483 via_write(via2_regp
, vIFR
, 0x82);
1485 #ifdef CONFIG_BLK_DEV_MAC_IDE
1487 if (mac_ide_intr_hook
)
1488 /* 'slot' is lacking the machspec bit in 2.0 */
1489 /* need to pass proper dev_id = hwgroup here */
1490 mac_ide_intr_hook(IRQ_MAC_NUBUS
, via
, regs
);
1496 map
= ~via_read(rbv_regp
, rBufA
);
1498 map
= ~via_read(via2_regp
, vBufA
);
1500 if( (map
= (map
&nubus_active
)) ==0 ) {
1501 #ifdef DEBUG_NUBUS_INT
1502 printk("nubus_irq: nothing pending, map %x mask %x\n",
1508 #ifdef DEBUG_NUBUS_INT
1509 printk("nubus_irq: map %x mask %x\n", map
, nubus_active
);
1514 #ifdef DEBUG_NUBUS_INT
1515 printk("nubus stuck events - %d/%d\n", map
, nubus_active
);
1525 (nubus_handler
[i
].handler
)(i
+9, nubus_handler
[i
].dev_id
, regs
);
1530 via_write(rbv_regp
, rIFR
, 0x02);
1532 via_write(via2_regp
, vIFR
, 0x02);
1540 * Nubus dispatch handler - OSS style
1542 static void oss_do_nubus(int slot
, void *via
, struct pt_regs
*regs
)
1548 /* printk("nubus interrupt\n");*/
1551 /* lock the nubus interrupt */
1553 via_write(rbv_regp
, rIFR
, 0x82);
1555 via_write(via2_regp
, vIFR
, 0x82);
1558 /* IDE hack for Quadra: uses Nubus interrupt without any slot bit set */
1559 #ifdef CONFIG_BLK_DEV_MAC_IDE
1560 if (mac_ide_intr_hook
)
1561 mac_ide_intr_hook(IRQ_MAC_NUBUS
, via
, regs
);
1566 /* pending events */
1567 map
=(via_read(via
, nIFR
))&0x3F;
1569 #ifdef DEBUG_VIA_NUBUS
1570 printk("nubus_irq: map %x mask %x\n", map
, nubus_active
);
1572 if( (map
= (map
&nubus_active
)) ==0 ) {
1573 #ifdef CONFIG_BLK_DEV_MAC_IDE
1574 if (!mac_ide_intr_hook
)
1575 printk("nubus_irq: nothing pending, map %x mask %x\n",
1585 printk("nubus stuck events - %d/%d\n", map
, nubus_active
);
1596 (nubus_handler
[i
].handler
)((i
+9), nubus_handler
[i
].dev_id
, regs
);
1597 /* clear interrupt ?? */
1599 via_write(oss_regp
, i
, 0);
1605 via_write(oss_regp
, nIFR
, map
);