summaryrefslogtreecommitdiffstats
path: root/sys/amd64/pci
diff options
context:
space:
mode:
authorimp <imp@FreeBSD.org>2001-08-28 16:35:01 +0000
committerimp <imp@FreeBSD.org>2001-08-28 16:35:01 +0000
commit9c56de3f58ee9f71eb8262d77aa69d804f1603c2 (patch)
treecdb6e5649e73c2442f89954a76c956d0f332bc76 /sys/amd64/pci
parentf241788ed6ee61fb6a1b0c68aca37c5c79728478 (diff)
downloadFreeBSD-src-9c56de3f58ee9f71eb8262d77aa69d804f1603c2.zip
FreeBSD-src-9c56de3f58ee9f71eb8262d77aa69d804f1603c2.tar.gz
It turns out that while Toshiba laptops don't want to route interrupts
multiple times, others do. The last strategy, which was to assume that already routed interrupts were good and just return them doesn't work for some laptops. So, instead, we have a new strategy: we notice that we have an interrupt that's already routed. We go ahead and try to route it, none the less. We will assume that it is correctly routed, even if the route fails. We still assume that other failures in the bios32 call are because the interrupt is NOT routed. Note: some laptops do not support the bios32 interface to PCI BIOS and we need to call it via the INT 2A interface. That is another windmill to till at later. Also correct a minor typo and minor whitespace nits. Strong MFC candidate.
Diffstat (limited to 'sys/amd64/pci')
-rw-r--r--sys/amd64/pci/pci_cfgreg.c27
1 files changed, 10 insertions, 17 deletions
diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c
index d60241f..3d5afb7 100644
--- a/sys/amd64/pci/pci_cfgreg.c
+++ b/sys/amd64/pci/pci_cfgreg.c
@@ -236,6 +236,7 @@ pci_cfgintr(int bus, int device, int pin)
int i, irq;
struct bios_regs args;
u_int16_t v;
+ int already = 0;
v = pcibios_get_version();
if (v < 0x0210) {
@@ -256,41 +257,33 @@ pci_cfgintr(int bus, int device, int pin)
continue;
irq = pci_cfgintr_linked(pe, pin);
- if (irq != 255) {
- PRVERB(("pci_cfgintr: %d:%d INT%c already routed to irq %d\n",
- bus, device, 'A' + pin - 1, irq));
- return (irq);
- }
- irq = pci_cfgintr_unique(pe, pin);
+ if (irq != 255)
+ already = 1;
+ if (irq == 255)
+ irq = pci_cfgintr_unique(pe, pin);
if (irq == 255)
irq = pci_cfgintr_virgin(pe, pin);
-
+
if (irq == 255)
break;
-
-
+
/*
* Ask the BIOS to route the interrupt
*/
args.eax = PCIBIOS_ROUTE_INTERRUPT;
args.ebx = (bus << 8) | (device << 3);
args.ecx = (irq << 8) | (0xa + pin - 1); /* pin value is 0xa - 0xd */
- if (bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL))) {
+ if (bios32(&args, PCIbios.ventry, GSEL(GCODE_SEL, SEL_KPL)) && !already) {
/*
* XXX if it fails, we should try to smack the router
* hardware directly.
* XXX Also, there may be other choices that we can try that
* will work.
*/
- PRVERB(("pci_cfgintr: ROUTE_INTERRUPT failured.\n"));
+ PRVERB(("pci_cfgintr: ROUTE_INTERRUPT failed.\n"));
return(255);
}
-
- /*
- * XXX if it fails, we should try to smack the router hardware directly
- */
- PRVERB(("pci_cfgintr: %d:%d INT%c routed to irq %d\n",
- bus, device, 'A' + pin - 1, irq));
+ printf("pci_cfgintr: %d:%d INT%c routed to irq %d\n", bus, device, 'A' + pin - 1, irq);
return(irq);
}
OpenPOWER on IntegriCloud