Blame view

drivers/pci/irq.c 1.76 KB
388c8c16a   James Bottomley   PCI: add routines...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /*
   * 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)
  ",
1a9271331   Kay Sievers   PCI: struct devic...
19
  		   dev_name(&parent->dev), parent->vendor, parent->device);
388c8c16a   James Bottomley   PCI: add routines...
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
62
63
  	dev_printk(KERN_ERR, &pdev->dev, "%s
  ", reason);
  	dev_printk(KERN_ERR, &pdev->dev, "Please report to linux-kernel@vger.kernel.org
  ");
  	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);