diff options
author | Matthew Wilcox <matthew@wil.cx> | 2006-03-05 22:33:34 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-03-23 14:35:16 -0800 |
commit | 309e57df7b766172ba137a8cbd909f88dd76e8e9 (patch) | |
tree | 74cc85977654925c76c687e597c7586b9e75629b /drivers/pci | |
parent | 5eeca8e688b6affba4cd85262152fdd1b274ad33 (diff) |
[PATCH] PCI: Provide a boot parameter to disable MSI
Several drivers are starting to grow options to disable MSI. However,
it's often a host chipset issue, not something which individual drivers
should handle. So we add the pci=nomsi kernel parameter to allow the user
to disable MSI modes for systems we haven't added to the quirk list yet.
Signed-off-by: Matthew Wilcox <matthew@wil.cx>
Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
Acked-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/Kconfig | 4 | ||||
-rw-r--r-- | drivers/pci/msi.c | 10 | ||||
-rw-r--r-- | drivers/pci/pci.c | 8 | ||||
-rw-r--r-- | drivers/pci/pci.h | 2 |
4 files changed, 22 insertions, 2 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index d3dcce815d1..4d762fc4878 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 aea8b258b9b..a77e79c8c82 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 0bf6d254426..03af2323893 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 a6dfee2f6d2..8f3fb47ea67 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; |