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;
