Commit 6e8f7982 authored by John Clemens's avatar John Clemens Committed by Linus Torvalds

[PATCH] pci=usepirqmask option.

Last week I sent you a patch adding a config option to honor the pirq mask
in the PCI routing table.  On your suggestion, Cory Bell made it a command
line option using the pci= interface and we both agree with you, it's
-much- cleaner this way.

Patch against 2.5.6 (Cory's submitting for 2.4, I've tested and submitting
towards 2.5).  All credit goes to Cory Bell, with only minor input and
testing from myself.
parent 4414172f
......@@ -467,6 +467,14 @@ running once the system is up.
whatever the firmware may have
done.
usepirqmask [IA-32] Honor the possible IRQ mask
stored in the BIOS $PIR table. This is
needed on some systems with broken
BIOSes, notably some HP Pavilion N5400
and Omnibook XE3 notebooks. This will
have no effect if ACPI IRQ routing is
enabled.
pd. [PARIDE]
pf. [PARIDE]
......
......@@ -18,6 +18,7 @@
#define PCI_NO_SORT 0x0100
#define PCI_BIOS_SORT 0x0200
#define PCI_NO_CHECKS 0x0400
#define PCI_USE_PIRQ_MASK 0x0800
#define PCI_ASSIGN_ROMS 0x1000
#define PCI_BIOS_IRQ_SCAN 0x2000
#define PCI_ASSIGN_ALL_BUSSES 0x4000
......
......@@ -570,6 +570,10 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
* reported by the device if possible.
*/
newirq = dev->irq;
if (!((1 << newirq) & mask)) {
if ( pci_probe & PCI_USE_PIRQ_MASK) newirq = 0;
else printk(KERN_WARNING "PCI: IRQ %i for device %s doesn't match PIRQ mask - try pci=usepirqmask\n", newirq, dev->slot_name);
}
if (!newirq && assign) {
for (i = 0; i < 16; i++) {
if (!(mask & (1 << i)))
......@@ -588,7 +592,8 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
irq = pirq & 0xf;
DBG(" -> hardcoded IRQ %d\n", irq);
msg = "Hardcoded";
} else if (r->get && (irq = r->get(pirq_router_dev, dev, pirq))) {
} else if ( r->get && (irq = r->get(pirq_router_dev, dev, pirq)) && \
((!(pci_probe & PCI_USE_PIRQ_MASK)) || ((1 << irq) & mask)) ) {
DBG(" -> got IRQ %d\n", irq);
msg = "Found";
} else if (newirq && r->set && (dev->class >> 8) != PCI_CLASS_DISPLAY_VGA) {
......@@ -622,7 +627,9 @@ static int pcibios_lookup_irq(struct pci_dev *dev, int assign)
continue;
if (info->irq[pin].link == pirq) {
/* We refuse to override the dev->irq information. Give a warning! */
if (dev2->irq && dev2->irq != irq) {
if ( dev2->irq && dev2->irq != irq && \
(!(pci_probe & PCI_USE_PIRQ_MASK) || \
((1 << dev2->irq) & mask)) ) {
printk(KERN_INFO "IRQ routing conflict for %s, have irq %d, want irq %d\n",
dev2->slot_name, dev2->irq, irq);
continue;
......
......@@ -1343,6 +1343,9 @@ char * __devinit pcibios_setup(char *str)
} else if (!strcmp(str, "assign-busses")) {
pci_probe |= PCI_ASSIGN_ALL_BUSSES;
return NULL;
} else if (!strcmp(str, "usepirqmask")) {
pci_probe |= PCI_USE_PIRQ_MASK;
return NULL;
} else if (!strncmp(str, "irqmask=", 8)) {
pcibios_irq_mask = simple_strtol(str+8, NULL, 0);
return NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment