xref: /netbsd/sys/arch/evbmips/malta/pci/pcib.c (revision 6550d01e)
1 /*	$NetBSD: pcib.c,v 1.13 2009/08/19 15:13:56 dyoung Exp $	*/
2 
3 /*
4  * Copyright 2002 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Simon Burge for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed for the NetBSD Project by
20  *      Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: pcib.c,v 1.13 2009/08/19 15:13:56 dyoung Exp $");
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/device.h>
45 #include <sys/malloc.h>
46 
47 #include <machine/bus.h>
48 #include <evbmips/malta/maltareg.h>
49 #include <evbmips/malta/maltavar.h>
50 #include <evbmips/malta/dev/gtreg.h>
51 #include <evbmips/malta/pci/pcibvar.h>
52 
53 #include <dev/isa/isareg.h>
54 #include <dev/isa/isavar.h>
55 
56 #include <dev/pci/pcireg.h>
57 #include <dev/pci/pcivar.h>
58 #include <dev/pci/pcidevs.h>
59 
60 #include <dev/ic/i8259reg.h>
61 
62 
63 #define	ICU_LEN		16	/* number of ISA IRQs */
64 
65 const char *isa_intrnames[ICU_LEN] = {
66 	"timer",
67 	"keyboard",
68 	"reserved",		/* by South Bridge (for cascading) */
69 	"com1",
70 	"com0",
71 	"not used",
72 	"floppy",
73 	"centronics",
74 	"mcclock",
75 	"i2c",
76 	"pci A,B",		/* PCI slots 1..4, ethernet */
77 	"pci C,D",		/* PCI slots 1..4, audio, usb */
78 	"mouse",
79 	"reserved",
80 	"ide primary",
81 	"ide secondary",	/* and compact flash connector */
82 };
83 
84 struct pcib_intrhead {
85 	LIST_HEAD(, evbmips_intrhand) intr_q;
86 	struct evcnt intr_count;
87 	int intr_type;
88 };
89 
90 struct pcib_softc {
91 	struct device sc_dev;
92 
93 	bus_space_tag_t sc_iot;
94 	bus_space_handle_t sc_ioh_icu1;
95 	bus_space_handle_t sc_ioh_icu2;
96 	bus_space_handle_t sc_ioh_elcr;
97 
98 	struct mips_isa_chipset sc_ic;
99 
100 	struct pcib_intrhead sc_intrtab[ICU_LEN];
101 
102 	u_int16_t	sc_imask;
103 	u_int16_t	sc_elcr;
104 
105 	u_int16_t	sc_reserved;
106 
107 	void *sc_ih;
108 };
109 
110 /*
111  * XXX
112  *	There is only one pci-isa bridge, and all external interrupts
113  *	are routed through it, so we need to remember the softc when
114  *	called from other interrupt handling code.
115  */
116 static struct pcib_softc *my_sc;
117 struct mips_isa_chipset *pcib_ic;
118 
119 static int	pcib_match(struct device *, struct cfdata *, void *);
120 static void	pcib_attach(struct device *, struct device *, void *);
121 static int	pcib_intr(void *v);
122 static void	pcib_bridge_callback(struct device *);
123 static void	pcib_set_icus(struct pcib_softc *sc);
124 static void	pcib_cleanup(void *arg);
125 
126 static const struct evcnt *
127 		pcib_isa_intr_evcnt(void *, int);
128 static void	*pcib_isa_intr_establish(void *, int, int, int,
129 		    int (*)(void *), void *);
130 static void	pcib_isa_intr_disestablish(void *, void *);
131 static void	pcib_isa_attach_hook(struct device *, struct device *,
132 		    struct isabus_attach_args *);
133 static void	pcib_isa_detach_hook(isa_chipset_tag_t, device_t);
134 static int	pcib_isa_intr_alloc(void *, int, int, int *);
135 static const char *
136 		pcib_isa_intr_string(void *, int);
137 
138 CFATTACH_DECL(pcib, sizeof(struct pcib_softc),
139     pcib_match, pcib_attach, NULL, NULL);
140 
141 static int
142 pcib_match(struct device *parent, struct cfdata *match, void *aux)
143 {
144 	struct pci_attach_args *pa = aux;
145 
146 	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
147 	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA)
148 		return (1);
149 
150 	return (0);
151 }
152 
153 static void
154 pcib_attach(struct device *parent, struct device *self, void *aux)
155 {
156 	struct pci_attach_args *pa = aux;
157 	char devinfo[256];
158 	int i;
159 
160 	printf("\n");
161 
162 	if (my_sc != NULL)
163 		panic("pcib_attach: already attached!");
164 	my_sc = (void *)self;
165 
166 	/*
167 	 * Just print out a description and defer configuration
168 	 * until all PCI devices have been attached.
169 	 */
170 	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
171 	printf("%s: %s, (rev . 0x%02x)\n", self->dv_xname, devinfo,
172 	    PCI_REVISION(pa->pa_class));
173 
174 	my_sc->sc_iot = pa->pa_iot;
175 
176 	/*
177 	 * Map the PIC/ELCR registers.
178 	 */
179 	if (bus_space_map(my_sc->sc_iot, 0x4d0, 2, 0, &my_sc->sc_ioh_elcr) != 0)
180 		printf("%s: unable to map ELCR registers\n",
181 		    my_sc->sc_dev.dv_xname);
182 	if (bus_space_map(my_sc->sc_iot, IO_ICU1, 2, 0, &my_sc->sc_ioh_icu1) != 0)
183 		printf("%s: unable to map ICU1 registers\n",
184 		    my_sc->sc_dev.dv_xname);
185 	if (bus_space_map(my_sc->sc_iot, IO_ICU2, 2, 0, &my_sc->sc_ioh_icu2) != 0)
186 		printf("%s: unable to map ICU2 registers\n",
187 		    my_sc->sc_dev.dv_xname);
188 
189 	/* All interrupts default to "masked off". */
190 	my_sc->sc_imask = 0xffff;
191 
192 	/* All interrupts default to edge-triggered. */
193 	my_sc->sc_elcr = 0;
194 
195 	/*
196 	 * Initialize the 8259s.
197 	 */
198 	/* reset, program device, 4 bytes */
199 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu1, PIC_ICW1,
200 	    ICW1_SELECT | ICW1_IC4);
201 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu1, PIC_ICW2,
202 	    ICW2_VECTOR(0)/*XXX*/);
203 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu1, PIC_ICW3,
204 	    ICW3_CASCADE(2));
205 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu1, PIC_ICW4,
206 	    ICW4_8086);
207 
208 	/* mask all interrupts */
209 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu1, PIC_OCW1,
210 	    my_sc->sc_imask & 0xff);
211 
212 	/* enable special mask mode */
213 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu1, PIC_OCW3,
214 	    OCW3_SELECT | OCW3_SSMM | OCW3_SMM);
215 
216 	/* read IRR by default */
217 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu1, PIC_OCW3,
218 	    OCW3_SELECT | OCW3_RR);
219 
220 	/* reset, program device, 4 bytes */
221 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu2, PIC_ICW1,
222 	    ICW1_SELECT | ICW1_IC4);
223 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu2, PIC_ICW2,
224 	    ICW2_VECTOR(0)/*XXX*/);
225 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu2, PIC_ICW3,
226 	    ICW3_CASCADE(2));
227 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu2, PIC_ICW4,
228 	    ICW4_8086);
229 
230 	/* mask all interrupts */
231 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu2, PIC_OCW1,
232 	    my_sc->sc_imask & 0xff);
233 
234 	/* enable special mask mode */
235 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu2, PIC_OCW3,
236 	    OCW3_SELECT | OCW3_SSMM | OCW3_SMM);
237 
238 	/* read IRR by default */
239 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_icu2, PIC_OCW3,
240 	    OCW3_SELECT | OCW3_RR);
241 
242 	/*
243 	 * Default all interrupts to edge-triggered.
244 	 */
245 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_elcr, 0,
246 	    my_sc->sc_elcr & 0xff);
247 	bus_space_write_1(my_sc->sc_iot, my_sc->sc_ioh_elcr, 1,
248 	    (my_sc->sc_elcr >> 8) & 0xff);
249 
250 	/*
251 	 * Some ISA interrupts are reserved for devices that
252 	 * we know are hard-wired to certain IRQs.
253 	 */
254 	my_sc->sc_reserved =
255 		(1U << 0) |     /* timer */
256 		(1U << 1) |     /* keyboard controller (keyboard) */
257 		(1U << 2) |     /* PIC cascade */
258 		(1U << 3) |     /* COM 2 */
259 		(1U << 4) |     /* COM 1 */
260 		(1U << 6) |     /* floppy */
261 		(1U << 7) |     /* centronics */
262 		(1U << 8) |     /* RTC */
263 		(1U << 9) |	/* I2C */
264 		(1U << 12) |    /* keyboard controller (mouse) */
265 		(1U << 14) |    /* IDE primary */
266 		(1U << 15);     /* IDE secondary */
267 
268 	/* Set up our ISA chipset. */
269 	my_sc->sc_ic.ic_v = my_sc;
270 	my_sc->sc_ic.ic_intr_evcnt = pcib_isa_intr_evcnt;
271 	my_sc->sc_ic.ic_intr_establish = pcib_isa_intr_establish;
272 	my_sc->sc_ic.ic_intr_disestablish = pcib_isa_intr_disestablish;
273 	my_sc->sc_ic.ic_intr_alloc = pcib_isa_intr_alloc;
274 	my_sc->sc_ic.ic_intr_string = pcib_isa_intr_string;
275 
276 	pcib_ic = &my_sc->sc_ic;	/* XXX for external use */
277 
278 	/* Initialize our interrupt table. */
279 	for (i = 0; i < ICU_LEN; i++) {
280 #if 0
281 		char irqstr[8];		/* 4 + 2 + NULL + sanity */
282 
283 		sprintf(irqstr, "irq %d", i);
284 		evcnt_attach_dynamic(&my_sc->sc_intrtab[i].intr_count,
285 		    EVCNT_TYPE_INTR, NULL, "pcib", irqstr);
286 #else
287 		evcnt_attach_dynamic(&my_sc->sc_intrtab[i].intr_count,
288 		    EVCNT_TYPE_INTR, NULL, "pcib", isa_intrnames[i]);
289 #endif
290 		LIST_INIT(&my_sc->sc_intrtab[i].intr_q);
291 		my_sc->sc_intrtab[i].intr_type = IST_NONE;
292 	}
293 
294 	/* Hook up our interrupt handler. */
295 	my_sc->sc_ih = evbmips_intr_establish(MALTA_SOUTHBRIDGE_INTR, pcib_intr, my_sc);
296 	if (my_sc->sc_ih == NULL)
297 		printf("%s: WARNING: unable to register interrupt handler\n",
298 		    my_sc->sc_dev.dv_xname);
299 
300 
301 	/*
302 	 * Disable ISA interrupts before returning to YAMON.
303 	 */
304 	if (shutdownhook_establish(pcib_cleanup, my_sc) == NULL)
305 		panic("pcib_attach: could not establish shutdown hook");
306 
307 	config_defer(self, pcib_bridge_callback);
308 }
309 
310 static void
311 pcib_bridge_callback(struct device *self)
312 {
313 	struct pcib_softc *sc = (void *)self;
314 	struct malta_config *mcp = &malta_configuration;
315 	struct isabus_attach_args iba;
316 
317 	/*
318 	 * Attach the ISA bus behind this bridge.
319 	 */
320 	memset(&iba, 0, sizeof(iba));
321 
322 	iba.iba_iot = &mcp->mc_iot;
323 	iba.iba_memt = &mcp->mc_memt;
324 	iba.iba_dmat = &mcp->mc_isa_dmat;
325 
326 	iba.iba_ic = &sc->sc_ic;
327 	iba.iba_ic->ic_attach_hook = pcib_isa_attach_hook;
328 	iba.iba_ic->ic_detach_hook = pcib_isa_detach_hook;
329 
330 	config_found_ia(&sc->sc_dev, "isabus", &iba, isabusprint);
331 }
332 
333 static void
334 pcib_isa_attach_hook(struct device *parent, struct device *self,
335     struct isabus_attach_args *iba)
336 {
337 
338 	/* Nothing to do. */
339 }
340 
341 static void
342 pcib_isa_detach_hook(isa_chipset_tag_t ic, device_t self)
343 {
344 
345 	/* Nothing to do. */
346 }
347 
348 static void
349 pcib_set_icus(struct pcib_softc *sc)
350 {
351 
352 	/* Enable the cascade IRQ (2) if 8-15 is enabled. */
353 	if ((sc->sc_imask & 0xff00) != 0xff00)
354 		sc->sc_imask &= ~(1U << 2);
355 	else
356 		sc->sc_imask |= (1U << 2);
357 
358 	bus_space_write_1(sc->sc_iot, sc->sc_ioh_icu1, PIC_OCW1,
359 	    sc->sc_imask & 0xff);
360 	bus_space_write_1(sc->sc_iot, sc->sc_ioh_icu2, PIC_OCW1,
361 	    (sc->sc_imask >> 8) & 0xff);
362 
363 	bus_space_write_1(sc->sc_iot, sc->sc_ioh_elcr, 0,
364 	    sc->sc_elcr & 0xff);
365 	bus_space_write_1(sc->sc_iot, sc->sc_ioh_elcr, 1,
366 	    (sc->sc_elcr >> 8) & 0xff);
367 }
368 
369 static int
370 pcib_intr(void *v)
371 {
372 	struct pcib_softc *sc = v;
373 	struct evbmips_intrhand *ih;
374 	int irq;
375 
376 	for (;;) {
377 #if 1
378 		bus_space_write_1(sc->sc_iot, sc->sc_ioh_icu1, PIC_OCW3,
379 		    OCW3_SELECT | OCW3_POLL);
380 		irq = bus_space_read_1(sc->sc_iot, sc->sc_ioh_icu1, PIC_OCW3);
381 		if ((irq & OCW3_POLL_PENDING) == 0)
382 			return (1);
383 
384 		irq = OCW3_POLL_IRQ(irq);
385 
386 		if (irq == 2) {
387 			bus_space_write_1(sc->sc_iot, sc->sc_ioh_icu2,
388 			    PIC_OCW3, OCW3_SELECT | OCW3_POLL);
389 			irq = bus_space_read_1(sc->sc_iot, sc->sc_ioh_icu2,
390 			    PIC_OCW3);
391 			if (irq & OCW3_POLL_PENDING)
392 				irq = OCW3_POLL_IRQ(irq) + 8;
393 			else
394 				irq = 2;
395 		}
396 #else
397 		/* XXX - should be a function call to gt.c? */
398 		irq = GT_REGVAL(GT_PCI0_INTR_ACK) & 0xff;
399 
400 		/*
401 		 * From YAMON source code:
402 		 *
403 		 * IRQ7 is used to detect spurious interrupts.
404 		 * The interrupt acknowledge cycle returns IRQ7, if no
405 		 * interrupts is requested.
406 		 * We can differentiate between this situation and a
407 		 * "Normal" IRQ7 by reading the ISR.
408 		 */
409 
410 		if (irq == 7) {
411 			int reg;
412 
413 			bus_space_write_1(sc->sc_iot, sc->sc_ioh_icu1, PIC_OCW3,
414 			    OCW3_SELECT | OCW3_RR | OCW3_RIS);
415 			reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh_icu1,
416 			    PIC_OCW3);
417 			if (!(reg & (1 << 7)))
418 				break;	/* spurious interrupt */
419 		}
420 #endif
421 
422 		sc->sc_intrtab[irq].intr_count.ev_count++;
423 		LIST_FOREACH(ih, &sc->sc_intrtab[irq].intr_q, ih_q)
424 			(*ih->ih_func)(ih->ih_arg);
425 
426 		/* Send a specific EOI to the 8259. */
427 		if (irq > 7) {
428 			bus_space_write_1(sc->sc_iot, sc->sc_ioh_icu2,
429 			    PIC_OCW2, OCW2_SELECT | OCW2_EOI | OCW2_SL |
430 			    OCW2_ILS(irq & 7));
431 			irq = 2;
432 		}
433 
434 		bus_space_write_1(sc->sc_iot, sc->sc_ioh_icu1, PIC_OCW2,
435 		    OCW2_SELECT | OCW2_EOI | OCW2_SL | OCW2_ILS(irq));
436 	}
437 }
438 
439 const char *
440 pcib_isa_intr_string(void *v, int irq)
441 {
442 	static char irqstr[12];		/* 8 + 2 + NULL + sanity */
443 
444 	if (irq == 0 || irq >= ICU_LEN || irq == 2)
445 		panic("pcib_isa_intr_string: bogus isa irq 0x%x", irq);
446 
447 	sprintf(irqstr, "isa irq %d", irq);
448 	return (irqstr);
449 }
450 
451 const struct evcnt *
452 pcib_isa_intr_evcnt(void *v, int irq)
453 {
454 
455 	if (irq == 0 || irq >= ICU_LEN || irq == 2)
456 		panic("pcib_isa_intr_evcnt: bogus isa irq 0x%x", irq);
457 
458 	return (&my_sc->sc_intrtab[irq].intr_count);
459 }
460 
461 void *
462 pcib_isa_intr_establish(void *v, int irq, int type, int level,
463     int (*func)(void *), void *arg)
464 {
465 	struct evbmips_intrhand *ih;
466 	int s;
467 
468 	if (irq >= ICU_LEN || irq == 2 || type == IST_NONE)
469 		panic("pcib_isa_intr_establish: bad irq or type");
470 
471 	switch (my_sc->sc_intrtab[irq].intr_type) {
472 	case IST_NONE:
473 		my_sc->sc_intrtab[irq].intr_type = type;
474 		break;
475 
476 	case IST_EDGE:
477 	case IST_LEVEL:
478 		if (type == my_sc->sc_intrtab[irq].intr_type)
479 			break;
480 		/* FALLTHROUGH */
481 	case IST_PULSE:
482 		/*
483 		 * We can't share interrupts in this case.
484 		 */
485 		return (NULL);
486 	}
487 
488 	ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
489 	if (ih == NULL)
490 		return (NULL);
491 
492 	ih->ih_func = func;
493 	ih->ih_arg = arg;
494 	ih->ih_irq = irq;
495 
496 	s = splhigh();
497 
498 	/* Insert the handler into the table. */
499 	LIST_INSERT_HEAD(&my_sc->sc_intrtab[irq].intr_q, ih, ih_q);
500 	my_sc->sc_intrtab[irq].intr_type = type;
501 
502 	/* Enable it, set trigger mode. */
503 	my_sc->sc_imask &= ~(1 << irq);
504 	if (my_sc->sc_intrtab[irq].intr_type == IST_LEVEL)
505 		my_sc->sc_elcr |= (1 << irq);
506 	else
507 		my_sc->sc_elcr &= ~(1 << irq);
508 
509 	pcib_set_icus(my_sc);
510 
511 	splx(s);
512 
513 	return (ih);
514 }
515 
516 void
517 pcib_isa_intr_disestablish(void *v, void *arg)
518 {
519 	struct evbmips_intrhand *ih = arg;
520 	int s;
521 
522 	s = splhigh();
523 
524 	LIST_REMOVE(ih, ih_q);
525 
526 	/* If there are no more handlers on this IRQ, disable it. */
527 	if (LIST_FIRST(&my_sc->sc_intrtab[ih->ih_irq].intr_q) == NULL) {
528 		my_sc->sc_imask |= (1 << ih->ih_irq);
529 		pcib_set_icus(my_sc);
530 	}
531 
532 	splx(s);
533 
534 	free(ih, M_DEVBUF);
535 }
536 
537 static int
538 pcib_isa_intr_alloc(void *v, int mask, int type, int *irq)
539 {
540 	int i, tmp, bestirq, count;
541 	struct evbmips_intrhand *ih;
542 
543 	if (type == IST_NONE)
544 		panic("pcib_intr_alloc: bogus type");
545 
546 	bestirq = -1;
547 	count = -1;
548 
549 	mask &= ~my_sc->sc_reserved;
550 
551 	for (i = 0; i < ICU_LEN; i++) {
552 		if ((mask & (1 << i)) == 0)
553 			continue;
554 
555 		switch (my_sc->sc_intrtab[i].intr_type) {
556 		case IST_NONE:
557 			/*
558 			 * If nothing's using the IRQ, just return it.
559 			 */
560 			*irq = i;
561 			return (0);
562 
563 		case IST_EDGE:
564 		case IST_LEVEL:
565 			if (type != my_sc->sc_intrtab[i].intr_type)
566 				continue;
567 			/*
568 			 * If the IRQ is sharable, count the number of
569 			 * other handlers, and if it's smaller than the
570 			 * last IRQ like this, remember it.
571 			 */
572 			tmp = 0;
573 			for (ih = LIST_FIRST(&my_sc->sc_intrtab[i].intr_q);
574 				ih != NULL; ih = LIST_NEXT(ih, ih_q))
575 			tmp++;
576 			if (bestirq == -1 || count > tmp) {
577 				bestirq = i;
578 				count = tmp;
579 			}
580 			break;
581 
582 		case IST_PULSE:
583 		/* This just isn't sharable. */
584 		continue;
585 		}
586 	}
587 
588 	if (bestirq == -1)
589 		return (1);
590 
591 	*irq = bestirq;
592 	return (0);
593 }
594 
595 static void
596 pcib_cleanup(void *arg)
597 {
598 
599 	my_sc->sc_imask = 0xffff;
600 	pcib_set_icus(my_sc);
601 }
602