diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-28 16:26:12 +0100 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 16:26:12 +0100 |
commit | 7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch) | |
tree | e730a4565e0318140d2fbd2f0415d18a339d7336 /drivers/pci/irq.c | |
parent | 41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff) | |
parent | 0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff) | |
download | linux-7a9787e1eba95a166265e6a260cf30af04ef0a99.tar.gz |
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'drivers/pci/irq.c')
-rw-r--r-- | drivers/pci/irq.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/pci/irq.c b/drivers/pci/irq.c new file mode 100644 index 000000000000..6441dfa969a3 --- /dev/null +++ b/drivers/pci/irq.c @@ -0,0 +1,60 @@ +/* + * PCI IRQ failure handing code + * + * Copyright (c) 2008 James Bottomley <James.Bottomley@HansenPartnership.com> + */ + +#include <linux/acpi.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/pci.h> + +static void pci_note_irq_problem(struct pci_dev *pdev, const char *reason) +{ + struct pci_dev *parent = to_pci_dev(pdev->dev.parent); + + dev_printk(KERN_ERR, &pdev->dev, + "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n", + parent->dev.bus_id, parent->vendor, parent->device); + dev_printk(KERN_ERR, &pdev->dev, "%s\n", reason); + dev_printk(KERN_ERR, &pdev->dev, "Please report to linux-kernel@vger.kernel.org\n"); + WARN_ON(1); +} + +/** + * pci_lost_interrupt - reports a lost PCI interrupt + * @pdev: device whose interrupt is lost + * + * The primary function of this routine is to report a lost interrupt + * in a standard way which users can recognise (instead of blaming the + * driver). + * + * Returns: + * a suggestion for fixing it (although the driver is not required to + * act on this). + */ +enum pci_lost_interrupt_reason pci_lost_interrupt(struct pci_dev *pdev) +{ + if (pdev->msi_enabled || pdev->msix_enabled) { + enum pci_lost_interrupt_reason ret; + + if (pdev->msix_enabled) { + pci_note_irq_problem(pdev, "MSIX routing failure"); + ret = PCI_LOST_IRQ_DISABLE_MSIX; + } else { + pci_note_irq_problem(pdev, "MSI routing failure"); + ret = PCI_LOST_IRQ_DISABLE_MSI; + } + return ret; + } +#ifdef CONFIG_ACPI + if (!(acpi_disabled || acpi_noirq)) { + pci_note_irq_problem(pdev, "Potential ACPI misrouting please reboot with acpi=noirq"); + /* currently no way to fix acpi on the fly */ + return PCI_LOST_IRQ_DISABLE_ACPI; + } +#endif + pci_note_irq_problem(pdev, "unknown cause (not MSI or ACPI)"); + return PCI_LOST_IRQ_NO_INFORMATION; +} +EXPORT_SYMBOL(pci_lost_interrupt); |