From willy@parisc-linux.org Sun Mar 5 21:33:37 2006 Date: Sun, 5 Mar 2006 22:33:34 -0700 From: Matthew Wilcox Cc: "Randy.Dunlap" , Greg KH Subject: PCI: Provide a boot parameter to disable MSI Message-ID: <20060306053334.GO1598@parisc-linux.org> Content-Disposition: inline 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 Signed-off-by: Randy Dunlap Acked-by: Jeff Garzik Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 4 ++++ drivers/pci/Kconfig | 4 ++++ drivers/pci/msi.c | 10 ++++++++++ drivers/pci/pci.c | 8 ++++++-- drivers/pci/pci.h | 2 ++ 5 files changed, 26 insertions(+), 2 deletions(-) --- gregkh-2.6.orig/Documentation/kernel-parameters.txt +++ gregkh-2.6/Documentation/kernel-parameters.txt @@ -49,6 +49,7 @@ restrictions referred to are that the re 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 --- gregkh-2.6.orig/drivers/pci/Kconfig +++ gregkh-2.6/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 --- gregkh-2.6.orig/drivers/pci/msi.c +++ gregkh-2.6/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* de int pos, temp; u16 control; + if (!pci_msi_enable) + return; if (!dev) return; @@ -1152,6 +1157,11 @@ void msi_remove_pci_irq_vectors(struct p } } +void pci_no_msi(void) +{ + pci_msi_enable = 0; +} + EXPORT_SYMBOL(pci_enable_msi); EXPORT_SYMBOL(pci_disable_msi); EXPORT_SYMBOL(pci_enable_msix); --- gregkh-2.6.orig/drivers/pci/pci.c +++ gregkh-2.6/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; } --- gregkh-2.6.orig/drivers/pci/pci.h +++ gregkh-2.6/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;