FreeBSD/Linux Kernel Cross Reference
sys/i386/pci/pci_bus.c
1 /*
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD: releng/5.0/sys/i386/pci/pci_bus.c 106878 2002-11-13 21:30:44Z peter $
27 *
28 */
29
30 #include "opt_cpu.h"
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/malloc.h>
38
39 #include <pci/pcivar.h>
40 #include <pci/pcireg.h>
41 #include <pci/pcib_private.h>
42 #include <isa/isavar.h>
43 #include <machine/legacyvar.h>
44 #include <machine/pci_cfgreg.h>
45 #include <machine/segments.h>
46 #include <machine/cputypes.h>
47 #include <machine/pc/bios.h>
48 #include <machine/md_var.h>
49
50 #include "pcib_if.h"
51
52 static int pcibios_pcib_route_interrupt(device_t pcib, device_t dev,
53 int pin);
54
55 static int
56 nexus_pcib_maxslots(device_t dev)
57 {
58 return 31;
59 }
60
61 /* read configuration space register */
62
63 static u_int32_t
64 nexus_pcib_read_config(device_t dev, int bus, int slot, int func,
65 int reg, int bytes)
66 {
67 return(pci_cfgregread(bus, slot, func, reg, bytes));
68 }
69
70 /* write configuration space register */
71
72 static void
73 nexus_pcib_write_config(device_t dev, int bus, int slot, int func,
74 int reg, u_int32_t data, int bytes)
75 {
76 pci_cfgregwrite(bus, slot, func, reg, data, bytes);
77 }
78
79 /* route interrupt */
80
81 static int
82 nexus_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
83 {
84 return (pcibios_pcib_route_interrupt(pcib, dev, pin));
85 }
86
87 static const char *
88 nexus_pcib_is_host_bridge(int bus, int slot, int func,
89 u_int32_t id, u_int8_t class, u_int8_t subclass,
90 u_int8_t *busnum)
91 {
92 const char *s = NULL;
93 static u_int8_t pxb[4]; /* hack for 450nx */
94
95 *busnum = 0;
96
97 switch (id) {
98 case 0x12258086:
99 s = "Intel 824?? host to PCI bridge";
100 /* XXX This is a guess */
101 /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */
102 *busnum = bus;
103 break;
104 case 0x71208086:
105 s = "Intel 82810 (i810 GMCH) Host To Hub bridge";
106 break;
107 case 0x71228086:
108 s = "Intel 82810-DC100 (i810-DC100 GMCH) Host To Hub bridge";
109 break;
110 case 0x71248086:
111 s = "Intel 82810E (i810E GMCH) Host To Hub bridge";
112 break;
113 case 0x11308086:
114 s = "Intel 82815 (i815 GMCH) Host To Hub bridge";
115 break;
116 case 0x71808086:
117 s = "Intel 82443LX (440 LX) host to PCI bridge";
118 break;
119 case 0x71908086:
120 s = "Intel 82443BX (440 BX) host to PCI bridge";
121 break;
122 case 0x71928086:
123 s = "Intel 82443BX host to PCI bridge (AGP disabled)";
124 break;
125 case 0x71948086:
126 s = "Intel 82443MX host to PCI bridge";
127 break;
128 case 0x71a08086:
129 s = "Intel 82443GX host to PCI bridge";
130 break;
131 case 0x71a18086:
132 s = "Intel 82443GX host to AGP bridge";
133 break;
134 case 0x71a28086:
135 s = "Intel 82443GX host to PCI bridge (AGP disabled)";
136 break;
137 case 0x84c48086:
138 s = "Intel 82454KX/GX (Orion) host to PCI bridge";
139 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1);
140 break;
141 case 0x84ca8086:
142 /*
143 * For the 450nx chipset, there is a whole bundle of
144 * things pretending to be host bridges. The MIOC will
145 * be seen first and isn't really a pci bridge (the
146 * actual busses are attached to the PXB's). We need to
147 * read the registers of the MIOC to figure out the
148 * bus numbers for the PXB channels.
149 *
150 * Since the MIOC doesn't have a pci bus attached, we
151 * pretend it wasn't there.
152 */
153 pxb[0] = nexus_pcib_read_config(0, bus, slot, func,
154 0xd0, 1); /* BUSNO[0] */
155 pxb[1] = nexus_pcib_read_config(0, bus, slot, func,
156 0xd1, 1) + 1; /* SUBA[0]+1 */
157 pxb[2] = nexus_pcib_read_config(0, bus, slot, func,
158 0xd3, 1); /* BUSNO[1] */
159 pxb[3] = nexus_pcib_read_config(0, bus, slot, func,
160 0xd4, 1) + 1; /* SUBA[1]+1 */
161 return NULL;
162 case 0x84cb8086:
163 switch (slot) {
164 case 0x12:
165 s = "Intel 82454NX PXB#0, Bus#A";
166 *busnum = pxb[0];
167 break;
168 case 0x13:
169 s = "Intel 82454NX PXB#0, Bus#B";
170 *busnum = pxb[1];
171 break;
172 case 0x14:
173 s = "Intel 82454NX PXB#1, Bus#A";
174 *busnum = pxb[2];
175 break;
176 case 0x15:
177 s = "Intel 82454NX PXB#1, Bus#B";
178 *busnum = pxb[3];
179 break;
180 }
181 break;
182
183 /* AMD -- vendor 0x1022 */
184 case 0x30001022:
185 s = "AMD Elan SC520 host to PCI bridge";
186 #ifdef CPU_ELAN
187 init_AMD_Elan_sc520();
188 #else
189 printf("*** WARNING: kernel option CPU_ELAN missing"
190 " -- timekeeping may be wrong.\n");
191 #endif
192 break;
193 case 0x70061022:
194 s = "AMD-751 host to PCI bridge";
195 break;
196 case 0x700e1022:
197 s = "AMD-761 host to PCI bridge";
198 break;
199
200 /* SiS -- vendor 0x1039 */
201 case 0x04961039:
202 s = "SiS 85c496";
203 break;
204 case 0x04061039:
205 s = "SiS 85c501";
206 break;
207 case 0x06011039:
208 s = "SiS 85c601";
209 break;
210 case 0x55911039:
211 s = "SiS 5591 host to PCI bridge";
212 break;
213 case 0x00011039:
214 s = "SiS 5591 host to AGP bridge";
215 break;
216
217 /* VLSI -- vendor 0x1004 */
218 case 0x00051004:
219 s = "VLSI 82C592 Host to PCI bridge";
220 break;
221
222 /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */
223 /* totally. Please let me know if anything wrong. -F */
224 /* XXX need info on the MVP3 -- any takers? */
225 case 0x05981106:
226 s = "VIA 82C598MVP (Apollo MVP3) host bridge";
227 break;
228
229 /* AcerLabs -- vendor 0x10b9 */
230 /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
231 /* id is '10b9" but the register always shows "10b9". -Foxfair */
232 case 0x154110b9:
233 s = "AcerLabs M1541 (Aladdin-V) PCI host bridge";
234 break;
235
236 /* OPTi -- vendor 0x1045 */
237 case 0xc7011045:
238 s = "OPTi 82C700 host to PCI bridge";
239 break;
240 case 0xc8221045:
241 s = "OPTi 82C822 host to PCI Bridge";
242 break;
243
244 /* ServerWorks -- vendor 0x1166 */
245 case 0x00051166:
246 s = "ServerWorks NB6536 2.0HE host to PCI bridge";
247 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
248 break;
249
250 case 0x00061166:
251 /* FALLTHROUGH */
252 case 0x00081166:
253 /* FALLTHROUGH */
254 case 0x02011166:
255 /* FALLTHROUGH */
256 case 0x010f1014: /* IBM re-badged ServerWorks chipset */
257 s = "ServerWorks host to PCI bridge";
258 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
259 break;
260
261 case 0x00091166:
262 s = "ServerWorks NB6635 3.0LE host to PCI bridge";
263 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
264 break;
265
266 case 0x00101166:
267 s = "ServerWorks CIOB30 host to PCI bridge";
268 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
269 break;
270
271 case 0x00111166:
272 /* FALLTHROUGH */
273 case 0x03021014: /* IBM re-badged ServerWorks chipset */
274 s = "ServerWorks CMIC-HE host to PCI-X bridge";
275 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
276 break;
277
278 /* XXX unknown chipset, but working */
279 case 0x00171166:
280 /* FALLTHROUGH */
281 case 0x01011166:
282 s = "ServerWorks host to PCI bridge(unknown chipset)";
283 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
284 break;
285
286 /* Integrated Micro Solutions -- vendor 0x10e0 */
287 case 0x884910e0:
288 s = "Integrated Micro Solutions VL Bridge";
289 break;
290
291 default:
292 if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST)
293 s = "Host to PCI bridge";
294 break;
295 }
296
297 return s;
298 }
299
300 /*
301 * Scan the first pci bus for host-pci bridges and add pcib instances
302 * to the nexus for each bridge.
303 */
304 static void
305 nexus_pcib_identify(driver_t *driver, device_t parent)
306 {
307 int bus, slot, func;
308 u_int8_t hdrtype;
309 int found = 0;
310 int pcifunchigh;
311 int found824xx = 0;
312 int found_orion = 0;
313 int found_pcibios_flaming_death = 0;
314 device_t child;
315 devclass_t pci_devclass;
316
317 if (pci_cfgregopen() == 0)
318 return;
319 /*
320 * Check to see if we haven't already had a PCI bus added
321 * via some other means. If we have, bail since otherwise
322 * we're going to end up duplicating it.
323 */
324 if ((pci_devclass = devclass_find("pci")) &&
325 devclass_get_device(pci_devclass, 0))
326 return;
327
328
329 bus = 0;
330 retry:
331 for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
332 func = 0;
333 hdrtype = nexus_pcib_read_config(0, bus, slot, func,
334 PCIR_HEADERTYPE, 1);
335 if ((hdrtype & PCIM_MFDEV) &&
336 (!found_orion || hdrtype != 0xff))
337 pcifunchigh = 7;
338 else
339 pcifunchigh = 0;
340 for (func = 0; func <= pcifunchigh; func++) {
341 /*
342 * Read the IDs and class from the device.
343 */
344 u_int32_t id;
345 u_int8_t class, subclass, busnum;
346 const char *s;
347 device_t *devs;
348 int ndevs, i;
349
350 id = nexus_pcib_read_config(0, bus, slot, func,
351 PCIR_DEVVENDOR, 4);
352 if (id == -1)
353 continue;
354 class = nexus_pcib_read_config(0, bus, slot, func,
355 PCIR_CLASS, 1);
356 subclass = nexus_pcib_read_config(0, bus, slot, func,
357 PCIR_SUBCLASS, 1);
358
359 s = nexus_pcib_is_host_bridge(bus, slot, func,
360 id, class, subclass,
361 &busnum);
362 if (s == NULL)
363 continue;
364
365 /*
366 * Check to see if the physical bus has already
367 * been seen. Eg: hybrid 32 and 64 bit host
368 * bridges to the same logical bus.
369 */
370 if (device_get_children(parent, &devs, &ndevs) == 0) {
371 for (i = 0; s != NULL && i < ndevs; i++) {
372 if (strcmp(device_get_name(devs[i]),
373 "pcib") != 0)
374 continue;
375 if (legacy_get_pcibus(devs[i]) == busnum)
376 s = NULL;
377 }
378 free(devs, M_TEMP);
379 }
380
381 if (s == NULL)
382 continue;
383 /*
384 * Add at priority 100 to make sure we
385 * go after any motherboard resources
386 */
387 child = BUS_ADD_CHILD(parent, 100,
388 "pcib", busnum);
389 device_set_desc(child, s);
390 legacy_set_pcibus(child, busnum);
391
392 found = 1;
393 if (id == 0x12258086)
394 found824xx = 1;
395 if (id == 0x84c48086)
396 found_orion = 1;
397 }
398 }
399 if (found824xx && bus == 0) {
400 bus++;
401 goto retry;
402 }
403
404 /*
405 * This is just freaking brilliant! Some BIOS writers have
406 * decided that we must be forcibly prevented from using
407 * PCIBIOS to query the host->pci bridges. If you try and
408 * access configuration registers, it pretends there is
409 * no pci device at that bus:device:function address.
410 */
411 if (!found && pci_pcibios_active() && !found_pcibios_flaming_death) {
412 /* retry with the old mechanism, or fail */
413 if (pci_kill_pcibios() == 0)
414 return;
415 printf("nexus_pcib_identify: found broken PCIBIOS - disabling it and retrying.\n");
416 printf("nexus_pcib_identify: it is bogusly censoring host->pci bridges.\n");
417 found_pcibios_flaming_death = 1;
418 goto retry;
419 }
420
421 /*
422 * Make sure we add at least one bridge since some old
423 * hardware doesn't actually have a host-pci bridge device.
424 * Note that pci_cfgregopen() thinks we have PCI devices..
425 */
426 if (!found) {
427 if (bootverbose)
428 printf(
429 "nexus_pcib_identify: no bridge found, adding pcib0 anyway\n");
430 child = BUS_ADD_CHILD(parent, 100, "pcib", 0);
431 legacy_set_pcibus(child, 0);
432 }
433 }
434
435 static int
436 nexus_pcib_probe(device_t dev)
437 {
438
439 if (pci_cfgregopen() == 0)
440 return ENXIO;
441 return 0;
442 }
443
444 static int
445 nexus_pcib_attach(device_t dev)
446 {
447 device_t child;
448
449 child = device_add_child(dev, "pci", pcib_get_bus(dev));
450
451 return bus_generic_attach(dev);
452 }
453
454 static int
455 nexus_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
456 {
457
458 switch (which) {
459 case PCIB_IVAR_BUS:
460 *result = legacy_get_pcibus(dev);
461 return 0;
462 }
463 return ENOENT;
464 }
465
466 static int
467 nexus_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
468 {
469
470 switch (which) {
471 case PCIB_IVAR_BUS:
472 legacy_set_pcibus(dev, value);
473 return 0;
474 }
475 return ENOENT;
476 }
477
478
479 static device_method_t nexus_pcib_methods[] = {
480 /* Device interface */
481 DEVMETHOD(device_identify, nexus_pcib_identify),
482 DEVMETHOD(device_probe, nexus_pcib_probe),
483 DEVMETHOD(device_attach, nexus_pcib_attach),
484 DEVMETHOD(device_shutdown, bus_generic_shutdown),
485 DEVMETHOD(device_suspend, bus_generic_suspend),
486 DEVMETHOD(device_resume, bus_generic_resume),
487
488 /* Bus interface */
489 DEVMETHOD(bus_print_child, bus_generic_print_child),
490 DEVMETHOD(bus_read_ivar, nexus_pcib_read_ivar),
491 DEVMETHOD(bus_write_ivar, nexus_pcib_write_ivar),
492 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
493 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
494 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
495 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
496 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
497 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
498
499 /* pcib interface */
500 DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots),
501 DEVMETHOD(pcib_read_config, nexus_pcib_read_config),
502 DEVMETHOD(pcib_write_config, nexus_pcib_write_config),
503 DEVMETHOD(pcib_route_interrupt, nexus_pcib_route_interrupt),
504
505 { 0, 0 }
506 };
507
508 static driver_t nexus_pcib_driver = {
509 "pcib",
510 nexus_pcib_methods,
511 1,
512 };
513
514 DRIVER_MODULE(pcib, legacy, nexus_pcib_driver, pcib_devclass, 0, 0);
515
516
517 /*
518 * Provide a device to "eat" the host->pci bridges that we dug up above
519 * and stop them showing up twice on the probes. This also stops them
520 * showing up as 'none' in pciconf -l.
521 */
522 static int
523 pci_hostb_probe(device_t dev)
524 {
525 u_int32_t id;
526
527 id = pci_get_devid(dev);
528
529 switch (id) {
530
531 /* VIA VT82C596 Power Managment Function */
532 case 0x30501106:
533 return ENXIO;
534
535 default:
536 break;
537 }
538
539 if (pci_get_class(dev) == PCIC_BRIDGE &&
540 pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
541 device_set_desc(dev, "Host to PCI bridge");
542 device_quiet(dev);
543 return -10000;
544 }
545 return ENXIO;
546 }
547
548 static int
549 pci_hostb_attach(device_t dev)
550 {
551
552 return 0;
553 }
554
555 static device_method_t pci_hostb_methods[] = {
556 /* Device interface */
557 DEVMETHOD(device_probe, pci_hostb_probe),
558 DEVMETHOD(device_attach, pci_hostb_attach),
559 DEVMETHOD(device_shutdown, bus_generic_shutdown),
560 DEVMETHOD(device_suspend, bus_generic_suspend),
561 DEVMETHOD(device_resume, bus_generic_resume),
562
563 { 0, 0 }
564 };
565 static driver_t pci_hostb_driver = {
566 "hostb",
567 pci_hostb_methods,
568 1,
569 };
570 static devclass_t pci_hostb_devclass;
571
572 DRIVER_MODULE(hostb, pci, pci_hostb_driver, pci_hostb_devclass, 0, 0);
573
574
575 /*
576 * Install placeholder to claim the resources owned by the
577 * PCI bus interface. This could be used to extract the
578 * config space registers in the extreme case where the PnP
579 * ID is available and the PCI BIOS isn't, but for now we just
580 * eat the PnP ID and do nothing else.
581 *
582 * XXX we should silence this probe, as it will generally confuse
583 * people.
584 */
585 static struct isa_pnp_id pcibus_pnp_ids[] = {
586 { 0x030ad041 /* PNP0A03 */, "PCI Bus" },
587 { 0 }
588 };
589
590 static int
591 pcibus_pnp_probe(device_t dev)
592 {
593 int result;
594
595 if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcibus_pnp_ids)) <= 0)
596 device_quiet(dev);
597 return(result);
598 }
599
600 static int
601 pcibus_pnp_attach(device_t dev)
602 {
603 return(0);
604 }
605
606 static device_method_t pcibus_pnp_methods[] = {
607 /* Device interface */
608 DEVMETHOD(device_probe, pcibus_pnp_probe),
609 DEVMETHOD(device_attach, pcibus_pnp_attach),
610 DEVMETHOD(device_detach, bus_generic_detach),
611 DEVMETHOD(device_shutdown, bus_generic_shutdown),
612 DEVMETHOD(device_suspend, bus_generic_suspend),
613 DEVMETHOD(device_resume, bus_generic_resume),
614 { 0, 0 }
615 };
616
617 static driver_t pcibus_pnp_driver = {
618 "pcibus_pnp",
619 pcibus_pnp_methods,
620 1, /* no softc */
621 };
622
623 static devclass_t pcibus_pnp_devclass;
624
625 DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0);
626
627
628 /*
629 * Provide a PCI-PCI bridge driver for PCI busses behind PCI-PCI bridges
630 * that appear in the PCIBIOS Interrupt Routing Table to use the routing
631 * table for interrupt routing when possible.
632 */
633 static int pcibios_pcib_probe(device_t bus);
634
635 static device_method_t pcibios_pcib_pci_methods[] = {
636 /* Device interface */
637 DEVMETHOD(device_probe, pcibios_pcib_probe),
638 DEVMETHOD(device_attach, pcib_attach),
639 DEVMETHOD(device_shutdown, bus_generic_shutdown),
640 DEVMETHOD(device_suspend, bus_generic_suspend),
641 DEVMETHOD(device_resume, bus_generic_resume),
642
643 /* Bus interface */
644 DEVMETHOD(bus_print_child, bus_generic_print_child),
645 DEVMETHOD(bus_read_ivar, pcib_read_ivar),
646 DEVMETHOD(bus_write_ivar, pcib_write_ivar),
647 DEVMETHOD(bus_alloc_resource, pcib_alloc_resource),
648 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
649 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
650 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
651 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
652 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
653
654 /* pcib interface */
655 DEVMETHOD(pcib_maxslots, pcib_maxslots),
656 DEVMETHOD(pcib_read_config, pcib_read_config),
657 DEVMETHOD(pcib_write_config, pcib_write_config),
658 DEVMETHOD(pcib_route_interrupt, pcibios_pcib_route_interrupt),
659
660 {0, 0}
661 };
662
663 static driver_t pcibios_pcib_driver = {
664 "pcib",
665 pcibios_pcib_pci_methods,
666 sizeof(struct pcib_softc),
667 };
668
669 DRIVER_MODULE(pcibios_pcib, pci, pcibios_pcib_driver, pcib_devclass, 0, 0);
670
671 static int
672 pcibios_pcib_probe(device_t dev)
673 {
674
675 if ((pci_get_class(dev) != PCIC_BRIDGE) ||
676 (pci_get_subclass(dev) != PCIS_BRIDGE_PCI))
677 return (ENXIO);
678 if (pci_probe_route_table(pcib_get_bus(dev)) == 0)
679 return (ENXIO);
680 device_set_desc(dev, "PCIBIOS PCI-PCI bridge");
681 return (-2000);
682 }
683
684 static int
685 pcibios_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
686 {
687 return(pci_cfgintr(pci_get_bus(dev), pci_get_slot(dev), pin,
688 pci_get_irq(dev)));
689 }
Cache object: ad22da964dab9990c541fb895154f88c
|