xref: /netbsd-src/sys/arch/arc/isa/isabus.c (revision 274254cdae52594c1aa480a736aef78313d15c9c)
1 /*	$NetBSD: isabus.c,v 1.44 2008/07/05 08:46:25 tsutsui Exp $	*/
2 /*	$OpenBSD: isabus.c,v 1.15 1998/03/16 09:38:46 pefo Exp $	*/
3 /*	NetBSD: isa.c,v 1.33 1995/06/28 04:30:51 cgd Exp 	*/
4 
5 /*-
6  * Copyright (c) 1990 The Regents of the University of California.
7  * All rights reserved.
8  *
9  * This code is derived from software contributed to Berkeley by
10  * William Jolitz and Don Ahn.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *	@(#)isa.c	7.2 (Berkeley) 5/12/91
37  */
38 /*-
39  * Copyright (c) 1995 Per Fogelstrom
40  * Copyright (c) 1993, 1994 Charles M. Hannum.
41  *
42  * This code is derived from software contributed to Berkeley by
43  * William Jolitz and Don Ahn.
44  *
45  * Redistribution and use in source and binary forms, with or without
46  * modification, are permitted provided that the following conditions
47  * are met:
48  * 1. Redistributions of source code must retain the above copyright
49  *    notice, this list of conditions and the following disclaimer.
50  * 2. Redistributions in binary form must reproduce the above copyright
51  *    notice, this list of conditions and the following disclaimer in the
52  *    documentation and/or other materials provided with the distribution.
53  * 3. All advertising materials mentioning features or use of this software
54  *    must display the following acknowledgement:
55  *	This product includes software developed by the University of
56  *	California, Berkeley and its contributors.
57  * 4. Neither the name of the University nor the names of its contributors
58  *    may be used to endorse or promote products derived from this software
59  *    without specific prior written permission.
60  *
61  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
62  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
65  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
66  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
67  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
68  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
69  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
70  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
71  * SUCH DAMAGE.
72  *
73  *	@(#)isa.c	7.2 (Berkeley) 5/12/91
74  */
75 /*
76  * Mach Operating System
77  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
78  * All Rights Reserved.
79  *
80  * Permission to use, copy, modify and distribute this software and its
81  * documentation is hereby granted, provided that both the copyright
82  * notice and this permission notice appear in all copies of the
83  * software, derivative works or modified versions, and any portions
84  * thereof, and that both notices appear in supporting documentation.
85  *
86  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
87  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
88  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
89  *
90  * Carnegie Mellon requests users of this software to return to
91  *
92  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
93  *  School of Computer Science
94  *  Carnegie Mellon University
95  *  Pittsburgh PA 15213-3890
96  *
97  * any improvements or extensions that they make and grant Carnegie Mellon
98  * the rights to redistribute these changes.
99  */
100 /*
101   Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
102 
103 		All Rights Reserved
104 
105 Permission to use, copy, modify, and distribute this software and
106 its documentation for any purpose and without fee is hereby
107 granted, provided that the above copyright notice appears in all
108 copies and that both the copyright notice and this permission notice
109 appear in supporting documentation, and that the name of Intel
110 not be used in advertising or publicity pertaining to distribution
111 of the software without specific, written prior permission.
112 
113 INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
114 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
115 IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
116 CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
117 LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
118 NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
119 WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
120 */
121 
122 #include <sys/cdefs.h>
123 __KERNEL_RCSID(0, "$NetBSD: isabus.c,v 1.44 2008/07/05 08:46:25 tsutsui Exp $");
124 
125 #include <sys/param.h>
126 #include <sys/proc.h>
127 #include <sys/user.h>
128 #include <sys/systm.h>
129 #include <sys/callout.h>
130 #include <sys/time.h>
131 #include <sys/kernel.h>
132 #include <sys/device.h>
133 #include <sys/malloc.h>
134 #include <sys/extent.h>
135 
136 #include <uvm/uvm_extern.h>
137 
138 #include <machine/cpu.h>
139 #include <machine/pio.h>
140 #include <machine/autoconf.h>
141 #include <machine/intr.h>
142 
143 #include <mips/locore.h>
144 
145 #include <dev/ic/i8253reg.h>
146 #include <dev/ic/i8259reg.h>
147 #include <dev/isa/isareg.h>
148 #include <dev/isa/isavar.h>
149 #include <arc/isa/isabrvar.h>
150 #include <arc/isa/spkrreg.h>
151 
152 #include <arc/arc/timervar.h>
153 
154 static int beeping;
155 static callout_t sysbeep_ch;
156 
157 static long isa_mem_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
158 static long isa_io_ex_storage[EXTENT_FIXED_STORAGE_SIZE(16) / sizeof(long)];
159 
160 #define	IRQ_SLAVE	2
161 
162 /* Definition of the driver for autoconfig. */
163 static int isabrprint(void *, const char *);
164 
165 extern struct arc_bus_space arc_bus_io, arc_bus_mem;
166 
167 static void isabr_attach_hook(device_t , device_t,
168     struct isabus_attach_args *);
169 static const struct evcnt *isabr_intr_evcnt(isa_chipset_tag_t, int);
170 static void *isabr_intr_establish(isa_chipset_tag_t, int, int, int,
171     int (*)(void *), void *);
172 static void isabr_intr_disestablish(isa_chipset_tag_t, void*);
173 static void isabr_initicu(void);
174 static void intr_calculatemasks(void);
175 static int fakeintr(void *a);
176 
177 struct isabr_config *isabr_conf = NULL;
178 uint32_t imask[_IPL_N];	/* XXX */
179 
180 void
181 isabrattach(struct isabr_softc *sc)
182 {
183 	struct isabus_attach_args iba;
184 
185 	callout_init(&sysbeep_ch, 0);
186 
187 	if (isabr_conf == NULL)
188 		panic("isabr_conf isn't initialized");
189 
190 	aprint_normal("\n");
191 
192 	/* Initialize interrupt controller */
193 	isabr_initicu();
194 
195 	sc->arc_isa_cs.ic_attach_hook = isabr_attach_hook;
196 	sc->arc_isa_cs.ic_intr_evcnt = isabr_intr_evcnt;
197 	sc->arc_isa_cs.ic_intr_establish = isabr_intr_establish;
198 	sc->arc_isa_cs.ic_intr_disestablish = isabr_intr_disestablish;
199 
200 	arc_bus_space_init_extent(&arc_bus_mem, (void *)isa_mem_ex_storage,
201 	    sizeof(isa_mem_ex_storage));
202 	arc_bus_space_init_extent(&arc_bus_io, (void *)isa_io_ex_storage,
203 	    sizeof(isa_io_ex_storage));
204 
205 	iba.iba_iot = &arc_bus_io;
206 	iba.iba_memt = &arc_bus_mem;
207 	iba.iba_dmat = &sc->sc_dmat;
208 	iba.iba_ic = &sc->arc_isa_cs;
209 	config_found_ia(sc->sc_dev, "isabus", &iba, isabrprint);
210 }
211 
212 static int
213 isabrprint(void *aux, const char *pnp)
214 {
215 
216         if (pnp)
217                 aprint_normal("isa at %s", pnp);
218         aprint_verbose(" isa_io_base 0x%lx isa_mem_base 0x%lx",
219 	    arc_bus_io.bs_vbase, arc_bus_mem.bs_vbase);
220         return UNCONF;
221 }
222 
223 
224 /*
225  *	Interrupt system driver code
226  *	============================
227  */
228 #define LEGAL_IRQ(x)    ((x) >= 0 && (x) < ICU_LEN && (x) != 2)
229 
230 int	imen;
231 int	intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
232 struct isa_intrhand *isa_intrhand[ICU_LEN];
233 
234 static int
235 fakeintr(void *a)
236 {
237 
238 	return 0;
239 }
240 
241 /*
242  * Recalculate the interrupt masks from scratch.
243  * We could code special registry and deregistry versions of this function that
244  * would be faster, but the code would be nastier, and we don't expect this to
245  * happen very much anyway.
246  */
247 static void
248 intr_calculatemasks(void)
249 {
250 	int irq, level;
251 	struct isa_intrhand *q;
252 
253 	/* First, figure out which levels each IRQ uses. */
254 	for (irq = 0; irq < ICU_LEN; irq++) {
255 		int levels = 0;
256 		for (q = isa_intrhand[irq]; q; q = q->ih_next)
257 			levels |= 1 << q->ih_level;
258 		intrlevel[irq] = levels;
259 	}
260 
261 	/* Then figure out which IRQs use each level. */
262 	for (level = 0; level < _IPL_N; level++) {
263 		int irqs = 0;
264 		for (irq = 0; irq < ICU_LEN; irq++)
265 			if (intrlevel[irq] & (1 << level))
266 				irqs |= 1 << irq;
267 		imask[level] = irqs;
268 	}
269 
270 	imask[IPL_NONE] = 0;
271 
272 	imask[IPL_SOFTCLOCK] |= imask[IPL_NONE];
273 	imask[IPL_SOFTNET] |= imask[IPL_SOFTCLOCK];
274 
275 	/*
276 	 * Enforce a hierarchy that gives slow devices a better chance at not
277 	 * dropping data.
278 	 */
279 	imask[IPL_VM] |= imask[IPL_SOFTNET];
280 
281 	/*
282 	 * Since run queues may be manipulated by both the statclock and tty,
283 	 * network, and diskdrivers, clock > tty.
284 	 */
285 	imask[IPL_SCHED] |= imask[IPL_VM];
286 
287 	/* And eventually calculate the complete masks. */
288 	for (irq = 0; irq < ICU_LEN; irq++) {
289 		int irqs = 1 << irq;
290 		for (q = isa_intrhand[irq]; q; q = q->ih_next)
291 			irqs |= imask[q->ih_level];
292 		intrmask[irq] = irqs;
293 	}
294 
295 	/* Lastly, determine which IRQs are actually in use. */
296 	{
297 		int irqs = 0;
298 		for (irq = 0; irq < ICU_LEN; irq++)
299 			if (isa_intrhand[irq])
300 				irqs |= 1 << irq;
301 		if (irqs >= 0x100) /* any IRQs >= 8 in use */
302 			irqs |= 1 << IRQ_SLAVE;
303 		imen = ~irqs;
304 		isa_outb(IO_ICU1 + PIC_OCW1, imen);
305 		isa_outb(IO_ICU2 + PIC_OCW1, imen >> 8);
306 	}
307 }
308 
309 static void
310 isabr_attach_hook(struct device *parent, struct device *self,
311     struct isabus_attach_args *iba)
312 {
313 
314 	/* Nothing to do. */
315 }
316 
317 static const struct evcnt *
318 isabr_intr_evcnt(isa_chipset_tag_t ic, int irq)
319 {
320 
321 	/* XXX for now, no evcnt parent reported */
322 	return NULL;
323 }
324 
325 /*
326  *	Establish a ISA bus interrupt.
327  */
328 static void *
329 isabr_intr_establish(isa_chipset_tag_t ic, int irq, int type, int level,
330     int (*ih_fun)(void *), void *ih_arg)
331 {
332 	struct isa_intrhand **p, *q, *ih;
333 	static struct isa_intrhand fakehand = {NULL, fakeintr};
334 
335 	/* no point in sleeping unless someone can free memory. */
336 	ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
337 	if (ih == NULL)
338 		panic("isa_intr_establish: can't malloc handler info");
339 
340 	if (!LEGAL_IRQ(irq) || type == IST_NONE)
341 		panic("intr_establish: bogus irq or type");
342 
343 	switch (intrtype[irq]) {
344 	case IST_NONE:
345 		intrtype[irq] = type;
346 		break;
347 	case IST_EDGE:
348 	case IST_LEVEL:
349 		if (type == intrtype[irq])
350 			break;
351 	case IST_PULSE:
352 		if (type != IST_NONE)
353 			panic("intr_establish: can't share %s with %s",
354 			    isa_intr_typename(intrtype[irq]),
355 			    isa_intr_typename(type));
356 		break;
357 	}
358 
359 	/*
360 	 * Figure out where to put the handler.
361 	 * This is O(N^2), but we want to preserve the order, and N is
362 	 * generally small.
363 	 */
364 	for (p = &isa_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
365 		;
366 
367 	/*
368 	 * Actually install a fake handler momentarily, since we might be doing
369 	 * this with interrupts enabled and don't want the real routine called
370 	 * until masking is set up.
371 	 */
372 	fakehand.ih_level = level;
373 	*p = &fakehand;
374 
375 	intr_calculatemasks();
376 
377 	/*
378 	 * Poke the real handler in now.
379 	 */
380 	ih->ih_fun = ih_fun;
381 	ih->ih_arg = ih_arg;
382 	ih->ih_count = 0;
383 	ih->ih_next = NULL;
384 	ih->ih_level = level;
385 	ih->ih_irq = irq;
386 	snprintf(ih->ih_evname, sizeof(ih->ih_evname), "irq %d", irq);
387 	evcnt_attach_dynamic(&ih->ih_evcnt, EVCNT_TYPE_INTR, NULL, "isa",
388 	    ih->ih_evname);
389 	*p = ih;
390 
391 	return ih;
392 }
393 
394 static void
395 isabr_intr_disestablish(isa_chipset_tag_t ic, void *arg)
396 {
397 
398 }
399 
400 /*
401  *	Process an interrupt from the ISA bus.
402  */
403 uint32_t
404 isabr_iointr(uint32_t mask, struct clockframe *cf)
405 {
406 	struct isa_intrhand *ih;
407 	int isa_vector;
408 	int o_imen;
409 
410 	isa_vector = (*isabr_conf->ic_intr_status)();
411 	if (isa_vector < 0)
412 		return 0;
413 
414 	o_imen = imen;
415 	imen |= 1 << (isa_vector & (ICU_LEN - 1));
416 	if (isa_vector & 0x08) {
417 		isa_inb(IO_ICU2 + PIC_OCW1);
418 		isa_outb(IO_ICU2 + PIC_OCW1, imen >> 8);
419 		isa_outb(IO_ICU2 + PIC_OCW2,
420 		    OCW2_SELECT | OCW2_EOI | OCW2_SL |
421 		    OCW2_ILS((isa_vector & 7)));
422 		isa_outb(IO_ICU1,
423 		    OCW2_SELECT | OCW2_EOI | OCW2_SL | IRQ_SLAVE);
424 	} else {
425 		isa_inb(IO_ICU1 + PIC_OCW1);
426 		isa_outb(IO_ICU1 + PIC_OCW1, imen);
427 		isa_outb(IO_ICU1 + PIC_OCW2,
428 		    OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(isa_vector));
429 	}
430 	ih = isa_intrhand[isa_vector];
431 	if (isa_vector == 0 && ih) {	/* Clock */	/*XXX*/
432 		last_cp0_count = mips3_cp0_count_read();
433 		/* XXX: spllowerclock() not allowed */
434 		cf->sr &= ~MIPS_SR_INT_IE;
435 		if ((*ih->ih_fun)(cf))
436 			ih->ih_evcnt.ev_count++;
437 		ih = ih->ih_next;
438 	}
439 	while (ih) {
440 		if ((*ih->ih_fun)(ih->ih_arg))
441 			ih->ih_evcnt.ev_count++;
442 		ih = ih->ih_next;
443 	}
444 	imen = o_imen;
445 	isa_inb(IO_ICU1 + PIC_OCW1);
446 	isa_inb(IO_ICU2 + PIC_OCW1);
447 	isa_outb(IO_ICU1 + PIC_OCW1, imen);
448 	isa_outb(IO_ICU2 + PIC_OCW1, imen >> 8);
449 
450 	return MIPS_INT_MASK_2;
451 }
452 
453 
454 /*
455  * Initialize the Interrupt controller logic.
456  */
457 static void
458 isabr_initicu(void)
459 {
460 
461 	int i;
462 
463 	for (i = 0; i < ICU_LEN; i++) {
464 		switch (i) {
465 		case 2:
466 		case 8:
467 			intrtype[i] = IST_EDGE;
468 			break;
469 		default:
470 			intrtype[i] = IST_NONE;
471 			break;
472 		}
473 	}
474 
475 	/* reset; program device, four bytes */
476 	isa_outb(IO_ICU1 + PIC_ICW1, ICW1_SELECT | ICW1_IC4);
477 	/* starting at this vector index */
478 	isa_outb(IO_ICU1 + PIC_ICW2, 0);
479 	/* slave on line 2 */
480 	isa_outb(IO_ICU1 + PIC_ICW3, ICW3_CASCADE(IRQ_SLAVE));
481 	/* 8086 mode */
482 	isa_outb(IO_ICU1 + PIC_ICW4, ICW4_8086);
483 
484 	/* leave interrupts masked */
485 	isa_outb(IO_ICU1 + PIC_OCW1, 0xff);
486 
487 	/* special mask mode (if available) */
488 	isa_outb(IO_ICU1 + PIC_OCW3, OCW3_SELECT | OCW3_SSMM | OCW3_SMM);
489 	/* Read IRR by default. */
490 	isa_outb(IO_ICU1 + PIC_OCW3, OCW3_SELECT | OCW3_RR);
491 #ifdef REORDER_IRQ
492 	/* pri order 3-7, 0-2 (com2 first) */
493 	isa_outb(IO_ICU1 + PIC_OCW2,
494 	    OCW2_SELECT | OCW2_R | OCW2_SL OCW2_ILS(3 - 1));
495 #endif
496 
497 	/* reset; program device, four bytes */
498 	isa_outb(IO_ICU2 + PIC_ICW1, ICW1_SELECT | ICW1_IC4);
499 	/* staring at this vector index */
500 	isa_outb(IO_ICU2 + PIC_ICW2, 8);
501 	/* slave connected to line 2 of master */
502 	isa_outb(IO_ICU2 + PIC_ICW3, ICW3_SIC(IRQ_SLAVE));
503 	/* 8086 mode */
504 	isa_outb(IO_ICU2 + PIC_ICW4, ICW4_8086);
505 
506 	/* leave interrupts masked */
507 	isa_outb(IO_ICU2 + PIC_OCW1, 0xff);
508 
509 	/* special mask mode (if available) */
510 	isa_outb(IO_ICU2 + PIC_OCW3, OCW3_SELECT | OCW3_SSMM | OCW3_SMM);
511 	/* Read IRR by default. */
512 	isa_outb(IO_ICU2 + PIC_OCW3, OCW3_SELECT | OCW3_RR);
513 }
514 
515 
516 /*
517  *	SPEAKER BEEPER...
518  */
519 void
520 sysbeepstop(void *arg)
521 {
522 	int s;
523 
524 	/* disable counter 2 */
525 	s = splhigh();
526 	isa_outb(PITAUX_PORT, isa_inb(PITAUX_PORT) & ~PIT_SPKR);
527 	splx(s);
528 	beeping = 0;
529 }
530 
531 void
532 sysbeep(int pitch, int period)
533 {
534 	static int last_pitch, last_period;
535 	int s;
536 
537 	if (cold)
538 		return;		/* Can't beep yet. */
539 
540 	if (beeping)
541 		callout_stop(&sysbeep_ch);
542 	if (!beeping || last_pitch != pitch) {
543 		s = splhigh();
544 		isa_outb(IO_TIMER1 + TIMER_MODE,
545 		    TIMER_SEL2 | TIMER_16BIT | TIMER_SQWAVE);
546 		isa_outb(IO_TIMER1 + TIMER_CNTR2, TIMER_DIV(pitch) % 256);
547 		isa_outb(IO_TIMER1 + TIMER_CNTR2, TIMER_DIV(pitch) / 256);
548 		isa_outb(PITAUX_PORT, isa_inb(PITAUX_PORT) | PIT_SPKR);
549 		splx(s);
550 	}
551 	last_pitch = pitch;
552 	beeping = last_period = period;
553 	callout_reset(&sysbeep_ch, period, sysbeepstop, NULL);
554 }
555 
556 int
557 isa_intr_alloc(isa_chipset_tag_t c, int mask, int type, int *irq_p)
558 {
559 	int irq;
560 	int maybe_irq = -1;
561 	int shared_depth = 0;
562 	mask &= 0x8b28; /* choose from 3, 5, 8, 9, 11, 15 XXX */
563 	for (irq = 0; mask != 0; mask >>= 1, irq++) {
564 		if ((mask & 1) == 0)
565 			continue;
566 		if (intrtype[irq] == IST_NONE) {
567 			*irq_p = irq;
568 			return 0;
569 		}
570 		/* Level interrupts can be shared */
571 		if (type == IST_LEVEL && intrtype[irq] == IST_LEVEL) {
572 			struct isa_intrhand *ih = isa_intrhand[irq];
573 			int depth;
574 			if (maybe_irq == -1) {
575  				maybe_irq = irq;
576 				continue;
577 			}
578 			for (depth = 0; ih != NULL; ih = ih->ih_next)
579 				depth++;
580 			if (depth < shared_depth) {
581 				maybe_irq = irq;
582 				shared_depth = depth;
583 			}
584 		}
585 	}
586 	if (maybe_irq != -1) {
587 		*irq_p = maybe_irq;
588 		return 0;
589 	}
590 	return 1;
591 }
592