Commit 309e57df authored by Matthew Wilcox's avatar Matthew Wilcox Committed by Greg Kroah-Hartman

[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: default avatarMatthew Wilcox <matthew@wil.cx>
Signed-off-by: default avatarRandy Dunlap <rdunlap@xenotime.net>
Acked-by: default avatarJeff Garzik <jeff@garzik.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 5eeca8e6
...@@ -49,6 +49,7 @@ restrictions referred to are that the relevant option is valid if: ...@@ -49,6 +49,7 @@ restrictions referred to are that the relevant option is valid if:
MCA MCA bus support is enabled. MCA MCA bus support is enabled.
MDA MDA console support is enabled. MDA MDA console support is enabled.
MOUSE Appropriate mouse support is enabled. MOUSE Appropriate mouse support is enabled.
MSI Message Signaled Interrupts (PCI).
MTD MTD support is enabled. MTD MTD support is enabled.
NET Appropriate network support is enabled. NET Appropriate network support is enabled.
NUMA NUMA support is enabled. NUMA NUMA support is enabled.
...@@ -1152,6 +1153,9 @@ running once the system is up. ...@@ -1152,6 +1153,9 @@ running once the system is up.
Mechanism 2. Mechanism 2.
nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI nommconf [IA-32,X86_64] Disable use of MMCONFIG for PCI
Configuration 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 nosort [IA-32] Don't sort PCI devices according to
order given by the PCI BIOS. This sorting is order given by the PCI BIOS. This sorting is
done to get a device order compatible with done to get a device order compatible with
......
...@@ -11,6 +11,10 @@ config PCI_MSI ...@@ -11,6 +11,10 @@ config PCI_MSI
generate an interrupt using an inbound Memory Write on its generate an interrupt using an inbound Memory Write on its
PCI bus instead of asserting a device IRQ pin. 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. If you don't know what to do here, say N.
config PCI_DEBUG config PCI_DEBUG
......
...@@ -765,8 +765,11 @@ void pci_disable_msi(struct pci_dev* dev) ...@@ -765,8 +765,11 @@ void pci_disable_msi(struct pci_dev* dev)
u16 control; u16 control;
unsigned long flags; unsigned long flags;
if (!pci_msi_enable)
return;
if (!dev) if (!dev)
return; return;
pos = pci_find_capability(dev, PCI_CAP_ID_MSI); pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
if (!pos) if (!pos)
return; return;
...@@ -1026,6 +1029,8 @@ void pci_disable_msix(struct pci_dev* dev) ...@@ -1026,6 +1029,8 @@ void pci_disable_msix(struct pci_dev* dev)
int pos, temp; int pos, temp;
u16 control; u16 control;
if (!pci_msi_enable)
return;
if (!dev) if (!dev)
return; return;
...@@ -1152,6 +1157,11 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) ...@@ -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_enable_msi);
EXPORT_SYMBOL(pci_disable_msi); EXPORT_SYMBOL(pci_disable_msi);
EXPORT_SYMBOL(pci_enable_msix); EXPORT_SYMBOL(pci_enable_msix);
......
...@@ -900,8 +900,12 @@ static int __devinit pci_setup(char *str) ...@@ -900,8 +900,12 @@ static int __devinit pci_setup(char *str)
if (k) if (k)
*k++ = 0; *k++ = 0;
if (*str && (str = pcibios_setup(str)) && *str) { if (*str && (str = pcibios_setup(str)) && *str) {
/* PCI layer options should be handled here */ if (!strcmp(str, "nomsi")) {
printk(KERN_ERR "PCI: Unknown option `%s'\n", str); pci_no_msi();
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
}
} }
str = k; str = k;
} }
......
...@@ -50,8 +50,10 @@ extern int pci_msi_quirk; ...@@ -50,8 +50,10 @@ extern int pci_msi_quirk;
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
void disable_msi_mode(struct pci_dev *dev, int pos, int type); void disable_msi_mode(struct pci_dev *dev, int pos, int type);
void pci_no_msi(void);
#else #else
static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { } static inline void disable_msi_mode(struct pci_dev *dev, int pos, int type) { }
static inline void pci_no_msi(void) { }
#endif #endif
extern int pcie_mch_quirk; extern int pcie_mch_quirk;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment