xref: /openbsd-src/sys/arch/i386/pci/pci_machdep.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: pci_machdep.c,v 1.45 2009/03/10 15:03:17 oga Exp $	*/
2 /*	$NetBSD: pci_machdep.c,v 1.28 1997/06/06 23:29:17 thorpej Exp $	*/
3 
4 /*-
5  * Copyright (c) 1997 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10  * NASA Ames Research Center.
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  *
21  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 /*
35  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
36  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
37  *
38  * Redistribution and use in source and binary forms, with or without
39  * modification, are permitted provided that the following conditions
40  * are met:
41  * 1. Redistributions of source code must retain the above copyright
42  *    notice, this list of conditions and the following disclaimer.
43  * 2. Redistributions in binary form must reproduce the above copyright
44  *    notice, this list of conditions and the following disclaimer in the
45  *    documentation and/or other materials provided with the distribution.
46  * 3. All advertising materials mentioning features or use of this software
47  *    must display the following acknowledgement:
48  *	This product includes software developed by Charles Hannum.
49  * 4. The name of the author may not be used to endorse or promote products
50  *    derived from this software without specific prior written permission.
51  *
52  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62  */
63 
64 /*
65  * Machine-specific functions for PCI autoconfiguration.
66  *
67  * On PCs, there are two methods of generating PCI configuration cycles.
68  * We try to detect the appropriate mechanism for this machine and set
69  * up a few function pointers to access the correct method directly.
70  *
71  * The configuration method can be hard-coded in the config file by
72  * using `options PCI_CONF_MODE=N', where `N' is the configuration mode
73  * as defined section 3.6.4.1, `Generating Configuration Cycles'.
74  */
75 
76 #include <sys/types.h>
77 #include <sys/param.h>
78 #include <sys/time.h>
79 #include <sys/systm.h>
80 #include <sys/errno.h>
81 #include <sys/device.h>
82 
83 #include <uvm/uvm_extern.h>
84 
85 #include <machine/bus.h>
86 #include <machine/pio.h>
87 #include <machine/i8259.h>
88 
89 #include "bios.h"
90 #if NBIOS > 0
91 #include <machine/biosvar.h>
92 extern bios_pciinfo_t *bios_pciinfo;
93 #endif
94 
95 #include <dev/isa/isavar.h>
96 #include <dev/pci/pcivar.h>
97 #include <dev/pci/pcireg.h>
98 #include <dev/pci/pcidevs.h>
99 #include <dev/pci/ppbreg.h>
100 
101 #include "ioapic.h"
102 
103 #include <machine/i82093var.h>
104 #if NIOAPIC > 0
105 #include <machine/mpbiosvar.h>
106 #endif
107 
108 #include "pcibios.h"
109 #if NPCIBIOS > 0
110 #include <i386/pci/pcibiosvar.h>
111 #endif
112 
113 int pci_mode = -1;
114 
115 struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
116 
117 #define	PCI_CONF_LOCK()							\
118 do {									\
119 	mtx_enter(&pci_conf_lock);					\
120 } while (0)
121 
122 #define	PCI_CONF_UNLOCK()						\
123 do {									\
124 	mtx_leave(&pci_conf_lock);					\
125 } while (0)
126 
127 #define	PCI_MODE1_ENABLE	0x80000000UL
128 #define	PCI_MODE1_ADDRESS_REG	0x0cf8
129 #define	PCI_MODE1_DATA_REG	0x0cfc
130 
131 #define	PCI_MODE2_ENABLE_REG	0x0cf8
132 #define	PCI_MODE2_FORWARD_REG	0x0cfa
133 
134 #define _m1tag(b, d, f) \
135 	(PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8))
136 #define _qe(bus, dev, fcn, vend, prod) \
137 	{_m1tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
138 struct {
139 	u_int32_t tag;
140 	pcireg_t id;
141 } pcim1_quirk_tbl[] = {
142 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1),
143 	/* XXX Triflex2 not tested */
144 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2),
145 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4),
146 	/* Triton needed for Connectix Virtual PC */
147 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX),
148 	/* Connectix Virtual PC 5 has a 440BX */
149 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP),
150 	{0, 0xffffffff} /* patchable */
151 };
152 #undef _m1tag
153 #undef _qe
154 
155 /*
156  * PCI doesn't have any special needs; just use the generic versions
157  * of these functions.
158  */
159 struct bus_dma_tag pci_bus_dma_tag = {
160 	NULL,			/* _cookie */
161 	_bus_dmamap_create,
162 	_bus_dmamap_destroy,
163 	_bus_dmamap_load,
164 	_bus_dmamap_load_mbuf,
165 	_bus_dmamap_load_uio,
166 	_bus_dmamap_load_raw,
167 	_bus_dmamap_unload,
168 	NULL,			/* _dmamap_sync */
169 	_bus_dmamem_alloc,
170 	_bus_dmamem_free,
171 	_bus_dmamem_map,
172 	_bus_dmamem_unmap,
173 	_bus_dmamem_mmap,
174 };
175 
176 void
177 pci_attach_hook(struct device *parent, struct device *self,
178     struct pcibus_attach_args *pba)
179 {
180 
181 #if NBIOS > 0
182 	if (pba->pba_bus == 0)
183 		printf(": configuration mode %d (%s)",
184 			pci_mode, (bios_pciinfo?"bios":"no bios"));
185 #else
186 	if (pba->pba_bus == 0)
187 		printf(": configuration mode %d", pci_mode);
188 #endif
189 }
190 
191 int
192 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
193 {
194 
195 	/*
196 	 * Bus number is irrelevant.  If Configuration Mechanism 2 is in
197 	 * use, can only have devices 0-15 on any bus.  If Configuration
198 	 * Mechanism 1 is in use, can have devices 0-32 (i.e. the `normal'
199 	 * range).
200 	 */
201 	if (pci_mode == 2)
202 		return (16);
203 	else
204 		return (32);
205 }
206 
207 pcitag_t
208 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
209 {
210 	pcitag_t tag;
211 
212 	switch (pci_mode) {
213 	case 1:
214 		if (bus >= 256 || device >= 32 || function >= 8)
215 			panic("pci_make_tag: bad request");
216 
217 		tag.mode1 = PCI_MODE1_ENABLE |
218 		    	(bus << 16) | (device << 11) | (function << 8);
219 		break;
220 	case 2:
221 		if (bus >= 256 || device >= 16 || function >= 8)
222 			panic("pci_make_tag: bad request");
223 
224 		tag.mode2.port = 0xc000 | (device << 8);
225 		tag.mode2.enable = 0xf0 | (function << 1);
226 		tag.mode2.forward = bus;
227 		break;
228 	default:
229 		panic("pci_make_tag: mode not configured");
230 	}
231 
232 	return tag;
233 }
234 
235 void
236 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp)
237 {
238 
239 	switch (pci_mode) {
240 	case 1:
241 		if (bp != NULL)
242 			*bp = (tag.mode1 >> 16) & 0xff;
243 		if (dp != NULL)
244 			*dp = (tag.mode1 >> 11) & 0x1f;
245 		if (fp != NULL)
246 			*fp = (tag.mode1 >> 8) & 0x7;
247 		break;
248 	case 2:
249 		if (bp != NULL)
250 			*bp = tag.mode2.forward & 0xff;
251 		if (dp != NULL)
252 			*dp = (tag.mode2.port >> 8) & 0xf;
253 		if (fp != NULL)
254 			*fp = (tag.mode2.enable >> 1) & 0x7;
255 		break;
256 	default:
257 		panic("pci_decompose_tag: mode not configured");
258 	}
259 }
260 
261 pcireg_t
262 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
263 {
264 	pcireg_t data;
265 
266 	PCI_CONF_LOCK();
267 	switch (pci_mode) {
268 	case 1:
269 		outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
270 		data = inl(PCI_MODE1_DATA_REG);
271 		outl(PCI_MODE1_ADDRESS_REG, 0);
272 		break;
273 	case 2:
274 		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
275 		outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
276 		data = inl(tag.mode2.port | reg);
277 		outb(PCI_MODE2_ENABLE_REG, 0);
278 		break;
279 	default:
280 		panic("pci_conf_read: mode not configured");
281 	}
282 	PCI_CONF_UNLOCK();
283 
284 	return data;
285 }
286 
287 void
288 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
289 {
290 
291 	PCI_CONF_LOCK();
292 	switch (pci_mode) {
293 	case 1:
294 		outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
295 		outl(PCI_MODE1_DATA_REG, data);
296 		outl(PCI_MODE1_ADDRESS_REG, 0);
297 		break;
298 	case 2:
299 		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
300 		outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
301 		outl(tag.mode2.port | reg, data);
302 		outb(PCI_MODE2_ENABLE_REG, 0);
303 		break;
304 	default:
305 		panic("pci_conf_write: mode not configured");
306 	}
307 	PCI_CONF_UNLOCK();
308 }
309 
310 int
311 pci_mode_detect(void)
312 {
313 
314 #ifdef PCI_CONF_MODE
315 #if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2)
316 	return (pci_mode = PCI_CONF_MODE);
317 #else
318 #error Invalid PCI configuration mode.
319 #endif
320 #else
321 	u_int32_t sav, val;
322 	int i;
323 	pcireg_t idreg;
324 
325 	if (pci_mode != -1)
326 		return (pci_mode);
327 
328 #if NBIOS > 0
329 	/*
330 	 * If we have PCI info passed from the BIOS, use the mode given there
331 	 * for all of this code.  If not, pass on through to the previous tests
332 	 * to try and divine the correct mode.
333 	 */
334 	if (bios_pciinfo != NULL) {
335 		if (bios_pciinfo->pci_chars & 0x2)
336 			return (pci_mode = 2);
337 
338 		if (bios_pciinfo->pci_chars & 0x1)
339 			return (pci_mode = 1);
340 
341 		/* We should never get here, but if we do, fall through... */
342 	}
343 #endif
344 
345 	/*
346 	 * We try to divine which configuration mode the host bridge wants.
347 	 *
348 	 * This should really be done using the PCI BIOS.  If we get here, the
349 	 * PCI BIOS does not exist, or the boot blocks did not provide the
350 	 * information.
351 	 */
352 
353 	sav = inl(PCI_MODE1_ADDRESS_REG);
354 
355 	pci_mode = 1; /* assume this for now */
356 	/*
357 	 * catch some known buggy implementations of mode 1
358 	 */
359 	for (i = 0; i < sizeof(pcim1_quirk_tbl) / sizeof(pcim1_quirk_tbl[0]);
360 	     i++) {
361 		pcitag_t t;
362 
363 		if (!pcim1_quirk_tbl[i].tag)
364 			break;
365 		t.mode1 = pcim1_quirk_tbl[i].tag;
366 		idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */
367 		if (idreg == pcim1_quirk_tbl[i].id) {
368 #ifdef DEBUG
369 			printf("known mode 1 PCI chipset (%08x)\n",
370 			       idreg);
371 #endif
372 			return (pci_mode);
373 		}
374 	}
375 
376 	/*
377 	 * Strong check for standard compliant mode 1:
378 	 * 1. bit 31 ("enable") can be set
379 	 * 2. byte/word access does not affect register
380  	 */
381 	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
382 	outb(PCI_MODE1_ADDRESS_REG + 3, 0);
383 	outw(PCI_MODE1_ADDRESS_REG + 2, 0);
384 	val = inl(PCI_MODE1_ADDRESS_REG);
385 	if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
386 #ifdef DEBUG
387 		printf("pci_mode_detect: mode 1 enable failed (%x)\n",
388 		       val);
389 #endif
390 		goto not1;
391 	}
392 	outl(PCI_MODE1_ADDRESS_REG, 0);
393 	val = inl(PCI_MODE1_ADDRESS_REG);
394 	if ((val & 0x80fffffc) != 0)
395 		goto not1;
396 	return (pci_mode);
397 not1:
398 	outl(PCI_MODE1_ADDRESS_REG, sav);
399 
400 	/*
401 	 * This mode 2 check is quite weak (and known to give false
402 	 * positives on some Compaq machines).
403 	 * However, this doesn't matter, because this is the
404 	 * last test, and simply no PCI devices will be found if
405 	 * this happens.
406 	 */
407 	outb(PCI_MODE2_ENABLE_REG, 0);
408 	outb(PCI_MODE2_FORWARD_REG, 0);
409 	if (inb(PCI_MODE2_ENABLE_REG) != 0 ||
410 	    inb(PCI_MODE2_FORWARD_REG) != 0)
411 		goto not2;
412 	return (pci_mode = 2);
413 not2:
414 	return (pci_mode = 0);
415 #endif
416 }
417 
418 int
419 pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
420 {
421 	int pin = pa->pa_rawintrpin;
422 	int line = pa->pa_intrline;
423 #if NIOAPIC > 0
424 	struct mp_intr_map *mip;
425 	int bus, dev, func;
426 #endif
427 
428 	if (pin == 0) {
429 		/* No IRQ used. */
430 		goto bad;
431 	}
432 
433 	if (pin > PCI_INTERRUPT_PIN_MAX) {
434 		printf("pci_intr_map: bad interrupt pin %d\n", pin);
435 		goto bad;
436 	}
437 
438 	ihp->tag = pa->pa_tag;
439 	ihp->line = line;
440 	ihp->pin = pin;
441 
442 #if NIOAPIC > 0
443 	pci_decompose_tag (pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
444 
445 	if (!(ihp->line & PCI_INT_VIA_ISA) && mp_busses != NULL) {
446 		/*
447 		 * Assumes 1:1 mapping between PCI bus numbers and
448 		 * the numbers given by the MP bios.
449 		 * XXX Is this a valid assumption?
450 		 */
451 		int mpspec_pin = (dev<<2)|(pin-1);
452 
453 		for (mip = mp_busses[bus].mb_intrs; mip != NULL; mip=mip->next) {
454 			if (mip->bus_pin == mpspec_pin) {
455 				ihp->line = mip->ioapic_ih | line;
456 				return 0;
457 			}
458 		}
459 
460 		if (pa->pa_bridgetag) {
461 			int swizpin = PPB_INTERRUPT_SWIZZLE(pin, dev);
462 			if (pa->pa_bridgeih[swizpin - 1].line != -1) {
463 				ihp->line = pa->pa_bridgeih[swizpin - 1].line;
464 				ihp->line |= line;
465 				return 0;
466 			}
467 		}
468 		/*
469 		 * No explicit PCI mapping found. This is not fatal,
470 		 * we'll try the ISA (or possibly EISA) mappings next.
471 		 */
472 	}
473 #endif
474 
475 #if NPCIBIOS > 0
476 	pci_intr_header_fixup(pa->pa_pc, pa->pa_tag, ihp);
477 	line = ihp->line & APIC_INT_LINE_MASK;
478 #endif
479 
480 	/*
481 	 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
482 	 * `unknown' or `no connection' on a PC.  We assume that a device with
483 	 * `no connection' either doesn't have an interrupt (in which case the
484 	 * pin number should be 0, and would have been noticed above), or
485 	 * wasn't configured by the BIOS (in which case we punt, since there's
486 	 * no real way we can know how the interrupt lines are mapped in the
487 	 * hardware).
488 	 *
489 	 * XXX
490 	 * Since IRQ 0 is only used by the clock, and we can't actually be sure
491 	 * that the BIOS did its job, we also recognize that as meaning that
492 	 * the BIOS has not configured the device.
493 	 */
494 	if (line == 0 || line == I386_PCI_INTERRUPT_LINE_NO_CONNECTION)
495 		goto bad;
496 
497 	if (line >= ICU_LEN) {
498 		printf("pci_intr_map: bad interrupt line %d\n", line);
499 		goto bad;
500 	}
501 	if (line == 2) {
502 		printf("pci_intr_map: changed line 2 to line 9\n");
503 		line = 9;
504 	}
505 
506 #if NIOAPIC > 0
507 	if (!(ihp->line & PCI_INT_VIA_ISA) && mp_busses != NULL) {
508 		if (mip == NULL && mp_isa_bus) {
509 			for (mip = mp_isa_bus->mb_intrs; mip != NULL;
510 			    mip = mip->next) {
511 				if (mip->bus_pin == line) {
512 					ihp->line = mip->ioapic_ih | line;
513 					return 0;
514 				}
515 			}
516 		}
517 		if (mip == NULL && mp_eisa_bus) {
518 			for (mip = mp_eisa_bus->mb_intrs;  mip != NULL;
519 			    mip = mip->next) {
520 				if (mip->bus_pin == line) {
521 					ihp->line = mip->ioapic_ih | line;
522 					return 0;
523 				}
524 			}
525 		}
526 		if (mip == NULL) {
527 			printf("pci_intr_map: "
528 			    "bus %d dev %d func %d pin %d; line %d\n",
529 			    bus, dev, func, pin, line);
530 			printf("pci_intr_map: no MP mapping found\n");
531 		}
532 	}
533 #endif
534 
535 	return 0;
536 
537 bad:
538 	ihp->line = -1;
539 	return 1;
540 }
541 
542 const char *
543 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
544 {
545 	static char irqstr[64];
546 	int line = ih.line & APIC_INT_LINE_MASK;
547 
548 #if NIOAPIC > 0
549 	if (ih.line & APIC_INT_VIA_APIC) {
550 		snprintf(irqstr, sizeof irqstr, "apic %d int %d (irq %d)",
551 		     APIC_IRQ_APIC(ih.line), APIC_IRQ_PIN(ih.line), line);
552 		return (irqstr);
553 	}
554 #endif
555 
556 	if (line == 0 || line >= ICU_LEN || line == 2)
557 		panic("pci_intr_string: bogus handle 0x%x", line);
558 
559 	snprintf(irqstr, sizeof irqstr, "irq %d", line);
560 	return (irqstr);
561 }
562 
563 #include "acpiprt.h"
564 #if NACPIPRT > 0
565 void	acpiprt_route_interrupt(int bus, int dev, int pin);
566 #endif
567 
568 void *
569 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
570     int (*func)(void *), void *arg, char *what)
571 {
572 	void *ret;
573 	int bus, dev;
574 	int l = ih.line & APIC_INT_LINE_MASK;
575 
576 	pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL);
577 #if NACPIPRT > 0
578 	acpiprt_route_interrupt(bus, dev, ih.pin);
579 #endif
580 
581 #if NIOAPIC > 0
582 	if (l != -1 && ih.line & APIC_INT_VIA_APIC)
583 		return (apic_intr_establish(ih.line, IST_LEVEL, level, func,
584 		    arg, what));
585 #endif
586 	if (l == 0 || l >= ICU_LEN || l == 2)
587 		panic("pci_intr_establish: bogus handle 0x%x", l);
588 
589 	ret = isa_intr_establish(NULL, l, IST_LEVEL, level, func, arg, what);
590 #if NPCIBIOS > 0
591 	if (ret)
592 		pci_intr_route_link(pc, &ih);
593 #endif
594 	return (ret);
595 }
596 
597 void
598 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
599 {
600 	/* XXX oh, unroute the pci int link? */
601 	isa_intr_disestablish(NULL, cookie);
602 }
603