lin
2025-07-30 fcd736bf35fd93b563e9bbf594f2aa7b62028cc9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
 * 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/export.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_err(&pdev->dev,
       "Potentially misrouted IRQ (Bridge %s %04x:%04x)\n",
       dev_name(&parent->dev), parent->vendor, parent->device);
   dev_err(&pdev->dev, "%s\n", reason);
   dev_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);