[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>
This commit is contained in:
Matthew Wilcox 2006-03-05 22:33:34 -07:00 committed by Greg Kroah-Hartman
parent 5eeca8e688
commit 309e57df7b
5 changed files with 26 additions and 2 deletions

View file

@ -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.
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

View file

@ -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

View file

@ -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)
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)
} }
} }
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);

View file

@ -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;
} }

View file

@ -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;