Trust the settings programmed by the BIOS over what the $PIR says.

Specifically, if the BIOS has programmed an IRQ for a device that doesn't
match the list of valid IRQs for the link, use it anyway as some BIOSes
don't correctly list the valid IRQs in the $PIR.  Also, allow the user
to specify an IRQ that $PIR claims is invalid as an override, but emit a
warning in that case.
This commit is contained in:
John Baldwin 2005-04-14 18:25:09 +00:00
parent 2326e092a7
commit 84c7fde72e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145083

View File

@ -324,22 +324,50 @@ pci_pir_initial_irqs(struct PIR_entry *entry, struct PIR_intpin *intpin,
pin = intpin - entry->pe_intpin;
pci_link = pci_pir_find_link(intpin->link);
irq = pci_pir_search_irq(entry->pe_bus, entry->pe_device, pin);
if (irq == PCI_INVALID_IRQ)
if (irq == PCI_INVALID_IRQ || irq == pci_link->pl_irq)
return;
if (pci_pir_valid_irq(pci_link, irq)) {
if (pci_link->pl_irq == PCI_INVALID_IRQ) {
pci_link->pl_irq = irq;
pci_link->pl_routed = 1;
} else if (pci_link->pl_irq != irq)
/*
* If we don't have an IRQ for this link yet, then we trust the
* BIOS, even if it seems invalid from the $PIR entries.
*/
if (pci_link->pl_irq == PCI_INVALID_IRQ) {
if (!pci_pir_valid_irq(pci_link, irq))
printf(
"$PIR: BIOS IRQ %d for %d.%d.INT%c does not match link %#x irq %d\n",
"$PIR: Using invalid BIOS IRQ %d from %d.%d.INT%c is for link %#x\n",
irq, entry->pe_bus, entry->pe_device, pin + 'A',
pci_link->pl_id, pci_link->pl_irq);
} else
pci_link->pl_id);
pci_link->pl_irq = irq;
pci_link->pl_routed = 1;
return;
}
/*
* We have an IRQ and it doesn't match the current IRQ for this
* link. If the new IRQ is invalid, then warn about it and ignore
* it. If the old IRQ is invalid and the new IRQ is valid, then
* prefer the new IRQ instead. If both IRQs are valid, then just
* use the first one. Note that if we ever get into this situation
* we are having to guess which setting the BIOS actually routed.
* Perhaps we should just give up instead.
*/
if (!pci_pir_valid_irq(pci_link, irq)) {
printf(
"$PIR: BIOS IRQ %d for %d.%d.INT%c is not valid for link %#x\n",
irq, entry->pe_bus, entry->pe_device, pin + 'A',
pci_link->pl_id);
} else if (!pci_pir_valid_irq(pci_link, pci_link->pl_irq)) {
printf(
"$PIR: Preferring valid BIOS IRQ %d from %d.%d.INT%c for link %#x to IRQ %d\n",
irq, entry->pe_bus, entry->pe_device, pin + 'A',
pci_link->pl_id, pci_link->pl_irq);
pci_link->pl_irq = irq;
pci_link->pl_routed = 1;
} else
printf(
"$PIR: BIOS IRQ %d for %d.%d.INT%c does not match link %#x irq %d\n",
irq, entry->pe_bus, entry->pe_device, pin + 'A',
pci_link->pl_id, pci_link->pl_irq);
}
/*
@ -386,9 +414,9 @@ pci_pir_parse(void)
}
/*
* Allow the user to override the IRQ for a given link device as
* long as the override is valid or is 255 or 0 to clear a preset
* IRQ.
* Allow the user to override the IRQ for a given link device. We
* allow invalid IRQs to be specified but warn about them. An IRQ
* of 255 or 0 clears any preset IRQ.
*/
i = 0;
TAILQ_FOREACH(pci_link, &pci_links, pl_links) {
@ -398,12 +426,14 @@ pci_pir_parse(void)
continue;
if (irq == 0)
irq = PCI_INVALID_IRQ;
if (irq == PCI_INVALID_IRQ ||
pci_pir_valid_irq(pci_link, irq)) {
pci_link->pl_routed = 0;
pci_link->pl_irq = irq;
i = 1;
}
if (irq != PCI_INVALID_IRQ &&
!pci_pir_valid_irq(pci_link, irq) && bootverbose)
printf(
"$PIR: Warning, IRQ %d for link %#x is not listed as valid\n",
irq, pci_link->pl_id);
pci_link->pl_routed = 0;
pci_link->pl_irq = irq;
i = 1;
}
if (bootverbose && i) {
printf("$PIR: Links after tunable overrides:\n");