diff -urN linux-2.5.5/Documentation/kernel-parameters.txt linux/Documentation/kernel-parameters.txt --- linux-2.5.5/Documentation/kernel-parameters.txt Tue Feb 19 21:11:03 2002 +++ linux/Documentation/kernel-parameters.txt Sun Mar 10 03:19:59 2002 @@ -467,6 +467,14 @@ 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] diff -urN linux-2.5.5/arch/i386/kernel/pci-i386.h linux/arch/i386/kernel/pci-i386.h --- linux-2.5.5/arch/i386/kernel/pci-i386.h Tue Feb 19 21:11:03 2002 +++ linux/arch/i386/kernel/pci-i386.h Sun Mar 10 03:19:59 2002 @@ -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 diff -urN linux-2.5.5/arch/i386/kernel/pci-irq.c linux/arch/i386/kernel/pci-irq.c --- linux-2.5.5/arch/i386/kernel/pci-irq.c Tue Feb 19 21:11:02 2002 +++ linux/arch/i386/kernel/pci-irq.c Sun Mar 10 03:19:59 2002 @@ -570,6 +570,10 @@ * 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 @@ 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 @@ 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; diff -urN linux-2.5.5/arch/i386/kernel/pci-pc.c linux/arch/i386/kernel/pci-pc.c --- linux-2.5.5/arch/i386/kernel/pci-pc.c Sun Mar 10 03:17:17 2002 +++ linux/arch/i386/kernel/pci-pc.c Sun Mar 10 03:19:59 2002 @@ -1343,6 +1343,9 @@ } 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;