diff options
author | imp <imp@FreeBSD.org> | 2001-08-28 16:35:01 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 2001-08-28 16:35:01 +0000 |
commit | 9c56de3f58ee9f71eb8262d77aa69d804f1603c2 (patch) | |
tree | cdb6e5649e73c2442f89954a76c956d0f332bc76 /sys/amd64/pci | |
parent | f241788ed6ee61fb6a1b0c68aca37c5c79728478 (diff) | |
download | FreeBSD-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.c | 27 |
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); } |