summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt4
-rw-r--r--drivers/pci/Kconfig4
-rw-r--r--drivers/pci/msi.c10
-rw-r--r--drivers/pci/pci.c8
-rw-r--r--drivers/pci/pci.h2
5 files changed, 26 insertions, 2 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 7b7382d0f758..44a25f3f51d1 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -49,6 +49,7 @@ restrictions referred to are that the relevant option is valid if:
MCA MCA bus support is enabled.
MDA MDA console support is enabled.
MOUSE Appropriate mouse support is enabled.
+ MSI Message Signaled Interrupts (PCI).
MTD MTD support is enabled.
NET Appropriate network support is enabled.
NUMA NUMA support is enabled.
@@ -1152,6 +1153,9 @@ running once the system is up.
Mechanism 2.
nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI
Configuration
+ nomsi [MSI] If the PCI_MSI kernel config parameter is
+ enabled, this kernel boot option can be used to
+ disable the use of MSI interrupts system-wide.
nosort [IA-32] Don't sort PCI devices according to
order given by the PCI BIOS. This sorting is
done to get a device order compatible with
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index d3dcce815d15..4d762fc4878c 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -11,6 +11,10 @@ config PCI_MSI
generate an interrupt using an inbound Memory Write on its
PCI bus instead of asserting a device IRQ pin.
+ Use of PCI MSI interrupts can be disabled at kernel boot time
+ by using the 'pci=nomsi' option. This disables MSI for the
+ entire system.
+
If you don't know what to do here, say N.
config PCI_DEBUG
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index aea8b258b9b8..a77e79c8c82e 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -765,8 +765,11 @@ void pci_disable_msi(struct pci_dev* dev)
u16 control;
unsigned long flags;
+ if (!pci_msi_enable)
+ return;
if (!dev)
return;
+
pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
if (!pos)
return;
@@ -1026,6 +1029,8 @@ void pci_disable_msix(struct pci_dev* dev)
int pos, temp;
u16 control;
+ if (!pci_msi_enable)
+ return;
if (!dev)
return;
@@ -1152,6 +1157,11 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev)
}
}
+void pci_no_msi(void)
+{
+ pci_msi_enable = 0;
+}
+
EXPORT_SYMBOL(pci_enable_msi);
EXPORT_SYMBOL(pci_disable_msi);
EXPORT_SYMBOL(pci_enable_msix);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 0bf6d254426b..03af23238939 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -900,8 +900,12 @@ static int __devinit pci_setup(char *str)
if (k)
*k++ = 0;
if (*str && (str = pcibios_setup(str)) && *str) {
- /* PCI layer options should be handled here */
- printk(KERN_ERR "PCI: Unknown option `%s'\n", str);
+ if (!strcmp(str, "nomsi")) {
+ pci_no_msi();
+ } else {
+ printk(KERN_ERR "PCI: Unknown option `%s'\n",
+ str);
+ }
}
str = k;
}
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index a6dfee2f6d2b..8f3fb47ea671 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -50,8 +50,10 @@ extern int pci_msi_quirk;
#ifdef CONFIG_PCI_MSI
void disable_msi_mode(struct pci_dev *dev, int pos, int type);
+void pci_no_msi(void);
#else
static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
+static inline void pci_no_msi(void) { }
#endif
extern int pcie_mch_quirk;