linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/6] Improve MSI detection v3
@ 2006-06-21  2:31 Brice Goglin
  2006-06-21  2:31 ` [PATCH 1/6] Merge existing MSI disabling quirks Brice Goglin
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Brice Goglin @ 2006-06-21  2:31 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel

[PATCH 0/6] Improve MSI detection v3

Here's another set of patches to cleanup MSI detection.
There's only blacklisting (cleanup for non-PCI-E chipsets and
addition of HT cap checks).

#1 - Merge existing MSI disabling quirks
#2 - Rename PCI_CAP_ID_HT_IRQCONF to PCI_CAP_ID_HT
#3 - Blacklist PCI-E chipsets depending on Hypertransport MSI capabality
#4 - Factorize common MSI detection code from pci_enable_msi() and msix()
#5 - Stop inheriting bus flags and check root chipset bus flags instead
#6 - Drop pci_msi_quirk

Only #3 brings an important feature. The others are mostly cosmetic.
#1 defines a generic quirk to disable MSI. It will probably end up being
used for lots of MSI-broken chipset.

These patches are against 2.6.17-rc6-mm2.

Brice Goglin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/6] Merge existing MSI disabling quirks
  2006-06-21  2:31 [PATCH 0/6] Improve MSI detection v3 Brice Goglin
@ 2006-06-21  2:31 ` Brice Goglin
  2006-06-21  2:32 ` [PATCH 2/6] Rename PCI_CAP_ID_HT_IRQCONF into PCI_CAP_ID_HT Brice Goglin
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Brice Goglin @ 2006-06-21  2:31 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel

[PATCH 1/6] Merge existing MSI disabling quirks

Merge existing MSI disabling quirks into a generic one that we will
use to blacklist all MSI-broken chipsets.
By the way, print the bus id of the device.

Signed-off-by: Brice Goglin <brice@myri.com>
---
 drivers/pci/quirks.c |   29 ++++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

Index: linux-mm/drivers/pci/quirks.c
===================================================================
--- linux-mm.orig/drivers/pci/quirks.c	2006-06-20 22:02:02.000000000 -0400
+++ linux-mm/drivers/pci/quirks.c	2006-06-20 22:03:53.000000000 -0400
@@ -586,12 +586,6 @@
 { 
         unsigned char revid, tmp;
         
-	if (dev->subordinate) {
-		printk(KERN_WARNING "PCI: MSI quirk detected. "
-		       "PCI_BUS_FLAGS_NO_MSI set for subordinate bus.\n");
-		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
-	}
-
         if (nr_ioapics == 0) 
                 return;
 
@@ -604,13 +598,6 @@
         }
 } 
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
-
-static void __init quirk_svw_msi(struct pci_dev *dev)
-{
-	pci_msi_quirk = 1;
-	printk(KERN_WARNING "PCI: MSI quirk detected. pci_msi_quirk set.\n");
-}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE, quirk_svw_msi );
 #endif /* CONFIG_X86_IO_APIC */
 
 
@@ -1556,6 +1543,22 @@
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,	0x1460,		quirk_p64h2_1k_io);
 
+#ifdef CONFIG_PCI_MSI
+/* Disable MSI on chipsets that are known to not support it */
+static void __devinit quirk_disable_msi(struct pci_dev *dev)
+{
+	if (dev->subordinate) {
+		printk(KERN_WARNING "PCI: MSI quirk detected. "
+		       "PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n",
+		       pci_name(dev));
+		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE,
+			quirk_disable_msi);
+#endif /* CONFIG_PCI_MSI */
+
 EXPORT_SYMBOL(pcie_mch_quirk);
 #ifdef CONFIG_HOTPLUG
 EXPORT_SYMBOL(pci_fixup_device);

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 2/6] Rename PCI_CAP_ID_HT_IRQCONF into PCI_CAP_ID_HT
  2006-06-21  2:31 [PATCH 0/6] Improve MSI detection v3 Brice Goglin
  2006-06-21  2:31 ` [PATCH 1/6] Merge existing MSI disabling quirks Brice Goglin
@ 2006-06-21  2:32 ` Brice Goglin
  2006-06-21  2:32 ` [PATCH 3/6] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality Brice Goglin
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Brice Goglin @ 2006-06-21  2:32 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel

[PATCH 2/6] Rename PCI_CAP_ID_HT_IRQCONF into PCI_CAP_ID_HT

0x08 is the HT capability, while PCI_CAP_ID_HT_IRQCONF would be
the subtype 0x80 that mpic_scan_ht_pic() uses.
Rename PCI_CAP_ID_HT_IRQCONF into PCI_CAP_ID_HT.

Signed-off-by: Brice Goglin <brice@myri.com>
---
 arch/powerpc/sysdev/mpic.c |    2 +-
 include/linux/pci_regs.h   |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

Index: linux-mm/arch/powerpc/sysdev/mpic.c
===================================================================
--- linux-mm.orig/arch/powerpc/sysdev/mpic.c	2006-06-20 22:02:04.000000000 -0400
+++ linux-mm/arch/powerpc/sysdev/mpic.c	2006-06-20 22:03:28.000000000 -0400
@@ -250,7 +250,7 @@
 	for (pos = readb(devbase + PCI_CAPABILITY_LIST); pos != 0;
 	     pos = readb(devbase + pos + PCI_CAP_LIST_NEXT)) {
 		u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
-		if (id == PCI_CAP_ID_HT_IRQCONF) {
+		if (id == PCI_CAP_ID_HT) {
 			id = readb(devbase + pos + 3);
 			if (id == 0x80)
 				break;
Index: linux-mm/include/linux/pci_regs.h
===================================================================
--- linux-mm.orig/include/linux/pci_regs.h	2006-06-20 22:02:04.000000000 -0400
+++ linux-mm/include/linux/pci_regs.h	2006-06-20 22:03:28.000000000 -0400
@@ -196,7 +196,7 @@
 #define  PCI_CAP_ID_MSI		0x05	/* Message Signalled Interrupts */
 #define  PCI_CAP_ID_CHSWP	0x06	/* CompactPCI HotSwap */
 #define  PCI_CAP_ID_PCIX	0x07	/* PCI-X */
-#define  PCI_CAP_ID_HT_IRQCONF	0x08	/* HyperTransport IRQ Configuration */
+#define  PCI_CAP_ID_HT		0x08	/* HyperTransport */
 #define  PCI_CAP_ID_VNDR	0x09	/* Vendor specific capability */
 #define  PCI_CAP_ID_SHPC 	0x0C	/* PCI Standard Hot-Plug Controller */
 #define  PCI_CAP_ID_EXP 	0x10	/* PCI Express */

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/6] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality
  2006-06-21  2:31 [PATCH 0/6] Improve MSI detection v3 Brice Goglin
  2006-06-21  2:31 ` [PATCH 1/6] Merge existing MSI disabling quirks Brice Goglin
  2006-06-21  2:32 ` [PATCH 2/6] Rename PCI_CAP_ID_HT_IRQCONF into PCI_CAP_ID_HT Brice Goglin
@ 2006-06-21  2:32 ` Brice Goglin
  2006-06-22 13:56   ` [PATCH 3/6 v4] " Brice Goglin
  2006-06-21  2:32 ` [PATCH 4/6] Factorize common MSI detection code from pci_enable_msi() and msix() Brice Goglin
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Brice Goglin @ 2006-06-21  2:32 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel

[PATCH 3/6] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality

Introduce msi_ht_cap_enabled() to check the MSI capability in the
Hypertransport configuration space.
It is used in a generic quirk quirk_msi_ht_cap() to check whether
MSI is enabled on hypertransport chipset, and a nVidia specific quirk
quirk_nvidia_ck804_msi_ht_cap() where two 2 HT MSI mappings have to
be checked.
Both quirks set the PCI_BUS_FLAGS_NO_MSI flags when MSI is disabled.

Signed-off-by: Brice Goglin <brice@myri.com>
---
This patch will conflict with
pci/pci-nvidia-quirk-to-make-aer-pci-e-extended-capability-visible.patch
(currently in Greg K-H's patchset) since they both add
PCI_DEVICE_ID_NVIDIA_CK804_PCIE in pci_ids.h.
The first part of the changes in include/linux/pci_ids.h would have
to be dropped.

 drivers/pci/quirks.c    |   64 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pci_ids.h |    2 +
 2 files changed, 66 insertions(+)

Index: linux-mm/drivers/pci/quirks.c
===================================================================
--- linux-mm.orig/drivers/pci/quirks.c	2006-06-20 22:03:27.000000000 -0400
+++ linux-mm/drivers/pci/quirks.c	2006-06-20 22:03:45.000000000 -0400
@@ -1557,6 +1557,70 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE,
 			quirk_disable_msi);
+
+/* Returns 1 if the HT MSI capability is found and enabled */
+static pci_bus_flags_t __devinit msi_ht_cap_enabled(struct pci_dev *dev)
+{
+	u8 cap_off;
+	int nbcap = 0;
+	cap_off = PCI_CAPABILITY_LIST - 1;
+
+	/* go through all caps looking for a hypertransport msi mapping */
+	while (pci_read_config_byte(dev, cap_off + 1, &cap_off) == 0 &&
+		nbcap++ <= 256 / 4) {
+		u32 cap_hdr;
+		if (cap_off == 0 || cap_off == 0xff)
+			break;
+		cap_off &= 0xfc;
+		/* msi mapping section according to hypertransport spec */
+		if (pci_read_config_dword(dev, cap_off, &cap_hdr) == 0
+		    && (cap_hdr & 0xff) == PCI_CAP_ID_HT /* hypertransport cap */
+		    && (cap_hdr & 0xf8000000) == 0xa8000000 /* msi mapping */) {
+			printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n",
+			       pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled");
+			return (cap_hdr & 0x10000) != 0; /* msi mapping cap enabled */
+		}
+	}
+	return 0;
+}
+
+/* Check the hypertransport MSI mapping to know whether MSI is enabled or not */
+static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
+{
+	if (!dev->subordinate)
+		return;
+
+	if (!msi_ht_cap_enabled(dev)) {
+		printk(KERN_WARNING "PCI: MSI quirk detected. "
+		       "PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n",
+		       pci_name(dev));
+		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, quirk_msi_ht_cap);
+
+/* The nVidia CK804 chipset may have 2 HT MSI mappings.
+ * MSI are supported if the MSI capability set in any of these mappings.
+ */
+static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+{
+	struct pci_dev *pdev;
+
+	if (!dev->subordinate)
+		return;
+
+	/* check HT MSI cap on this chipset and the root one.
+	 * a single one having MSI is enough to be sure that MSI are supported.
+	 */
+	pdev = pci_find_slot(dev->bus->number, 0);
+	if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
+		printk(KERN_WARNING "PCI: MSI quirk detected. "
+		       "PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n",
+		       pci_name(dev));
+		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap);
 #endif /* CONFIG_PCI_MSI */
 
 EXPORT_SYMBOL(pcie_mch_quirk);
Index: linux-mm/include/linux/pci_ids.h
===================================================================
--- linux-mm.orig/include/linux/pci_ids.h	2006-06-20 22:02:02.000000000 -0400
+++ linux-mm/include/linux/pci_ids.h	2006-06-20 22:03:30.000000000 -0400
@@ -1027,6 +1027,7 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_8		0x0056
 #define PCI_DEVICE_ID_NVIDIA_NVENET_9		0x0057
 #define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO	0x0059
+#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE		0x005d
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS	0x0064
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE	0x0065
 #define PCI_DEVICE_ID_NVIDIA_NVENET_2		0x0066
@@ -1405,6 +1406,7 @@
 #define PCI_DEVICE_ID_SERVERWORKS_LE	  0x0009
 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
 #define PCI_DEVICE_ID_SERVERWORKS_EPB	  0x0103
+#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE	0x0132
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4	  0x0200
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5	  0x0201
 #define PCI_DEVICE_ID_SERVERWORKS_CSB6    0x0203

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 4/6] Factorize common MSI detection code from pci_enable_msi() and msix()
  2006-06-21  2:31 [PATCH 0/6] Improve MSI detection v3 Brice Goglin
                   ` (2 preceding siblings ...)
  2006-06-21  2:32 ` [PATCH 3/6] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality Brice Goglin
@ 2006-06-21  2:32 ` Brice Goglin
  2006-06-21  2:32 ` [PATCH 5/6] Stop inheriting bus flags and check root chipset bus flags instead Brice Goglin
  2006-06-21  2:33 ` [PATCH 6/6] Drop pci_msi_quirk Brice Goglin
  5 siblings, 0 replies; 8+ messages in thread
From: Brice Goglin @ 2006-06-21  2:32 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel

[PATCH 4/6] Factorize common MSI detection code from pci_enable_msi() and msix()

pci_enable_msi() and pci_enable_msix() have to check same things
before enabling MSI. Factorize this code in pci_msi_supported().

Signed-off-by: Brice Goglin <brice@myri.com>
---
 drivers/pci/msi.c |   46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

Index: linux-mm/drivers/pci/msi.c
===================================================================
--- linux-mm.orig/drivers/pci/msi.c	2006-06-20 22:02:03.000000000 -0400
+++ linux-mm/drivers/pci/msi.c	2006-06-20 22:03:47.000000000 -0400
@@ -902,6 +902,28 @@
 }
 
 /**
+ * pci_msi_supported - check whether MSI may be enabled on device
+ * @dev: pointer to the pci_dev data structure of MSI device function
+ *
+ * Check parent busses for MSI flags, or disable except
+ * if forced.
+ **/
+static
+int pci_msi_supported(struct pci_dev * dev)
+{
+	struct pci_bus *bus;
+
+	if (!pci_msi_enable || !dev || dev->no_msi)
+		return -1;
+
+	for (bus = dev->bus; bus; bus = bus->parent)
+		if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+			return -1;
+
+	return 0;
+}
+
+/**
  * pci_enable_msi - configure device's MSI capability structure
  * @dev: pointer to the pci_dev data structure of MSI device function
  *
@@ -913,19 +935,11 @@
  **/
 int pci_enable_msi(struct pci_dev* dev)
 {
-	struct pci_bus *bus;
-	int pos, temp, status = -EINVAL;
+	int pos, temp, status;
 	u16 control;
 
-	if (!pci_msi_enable || !dev)
- 		return status;
-
-	if (dev->no_msi)
-		return status;
-
-	for (bus = dev->bus; bus; bus = bus->parent)
-		if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
-			return -EINVAL;
+	if (pci_msi_supported(dev) < 0)
+ 		return -EINVAL;
 
 	temp = dev->irq;
 
@@ -1135,22 +1149,14 @@
  **/
 int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
 {
-	struct pci_bus *bus;
 	int status, pos, nr_entries, free_vectors;
 	int i, j, temp;
 	u16 control;
 	unsigned long flags;
 
-	if (!pci_msi_enable || !dev || !entries)
+	if (!entries || pci_msi_supported(dev) < 0)
  		return -EINVAL;
 
-	if (dev->no_msi)
-		return -EINVAL;
-
-	for (bus = dev->bus; bus; bus = bus->parent)
-		if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
-			return -EINVAL;
-
 	status = msi_init();
 	if (status < 0)
 		return status;

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 5/6] Stop inheriting bus flags and check root chipset bus flags instead
  2006-06-21  2:31 [PATCH 0/6] Improve MSI detection v3 Brice Goglin
                   ` (3 preceding siblings ...)
  2006-06-21  2:32 ` [PATCH 4/6] Factorize common MSI detection code from pci_enable_msi() and msix() Brice Goglin
@ 2006-06-21  2:32 ` Brice Goglin
  2006-06-21  2:33 ` [PATCH 6/6] Drop pci_msi_quirk Brice Goglin
  5 siblings, 0 replies; 8+ messages in thread
From: Brice Goglin @ 2006-06-21  2:32 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel

[PATCH 5/6] Stop inheriting bus flags and check root chipset bus flags instead

Inheriting bus flags requires to set them during the PCI hierarchy is
scanned, with EARLY or HEADER quirks. But the subordinate bus has not
been set at this point, so the bus flags cannot be set.

Signed-off-by: Brice Goglin <brice@myri.com>
---
 drivers/pci/msi.c   |   13 +++++++++----
 drivers/pci/probe.c |    2 +-
 include/linux/pci.h |    2 +-
 3 files changed, 11 insertions(+), 6 deletions(-)

Index: linux-mm/drivers/pci/probe.c
===================================================================
--- linux-mm.orig/drivers/pci/probe.c	2006-06-20 22:02:01.000000000 -0400
+++ linux-mm/drivers/pci/probe.c	2006-06-20 22:03:31.000000000 -0400
@@ -351,7 +351,7 @@
 	child->parent = parent;
 	child->ops = parent->ops;
 	child->sysdata = parent->sysdata;
-	child->bus_flags = parent->bus_flags;
+	child->bus_flags = 0;
 	child->bridge = get_device(&bridge->dev);
 
 	child->class_dev.class = &pcibus_class;
Index: linux-mm/include/linux/pci.h
===================================================================
--- linux-mm.orig/include/linux/pci.h	2006-06-20 22:02:01.000000000 -0400
+++ linux-mm/include/linux/pci.h	2006-06-20 22:03:31.000000000 -0400
@@ -242,7 +242,7 @@
 	char		name[48];
 
 	unsigned short  bridge_ctl;	/* manage NO_ISA/FBB/et al behaviors */
-	pci_bus_flags_t bus_flags;	/* Inherited by child busses */
+	pci_bus_flags_t bus_flags;
 	struct device		*bridge;
 	struct class_device	class_dev;
 	struct bin_attribute	*legacy_io; /* legacy I/O for this bus */
Index: linux-mm/drivers/pci/msi.c
===================================================================
--- linux-mm.orig/drivers/pci/msi.c	2006-06-20 22:03:30.000000000 -0400
+++ linux-mm/drivers/pci/msi.c	2006-06-20 22:03:45.000000000 -0400
@@ -911,14 +911,19 @@
 static
 int pci_msi_supported(struct pci_dev * dev)
 {
-	struct pci_bus *bus;
+	struct pci_dev *pdev;
 
 	if (!pci_msi_enable || !dev || dev->no_msi)
 		return -1;
 
-	for (bus = dev->bus; bus; bus = bus->parent)
-		if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI)
-			return -1;
+	/* find root complex for our device */
+	pdev = dev;
+	while (pdev->bus && pdev->bus->self)
+		pdev = pdev->bus->self;
+
+	/* check its bus flags */
+	if (pdev->subordinate->bus_flags & PCI_BUS_FLAGS_NO_MSI)
+		return -1;
 
 	return 0;
 }

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 6/6] Drop pci_msi_quirk
  2006-06-21  2:31 [PATCH 0/6] Improve MSI detection v3 Brice Goglin
                   ` (4 preceding siblings ...)
  2006-06-21  2:32 ` [PATCH 5/6] Stop inheriting bus flags and check root chipset bus flags instead Brice Goglin
@ 2006-06-21  2:33 ` Brice Goglin
  5 siblings, 0 replies; 8+ messages in thread
From: Brice Goglin @ 2006-06-21  2:33 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel

[PATCH 6/6] Drop pci_msi_quirk

pci_msi_quirk is not used anymore and using bus_flags should be preferred.
Drop pci_msi_quirk completely.

Signed-off-by: Brice Goglin <brice@myri.com>
---
 drivers/pci/msi.c    |    7 -------
 drivers/pci/pci.h    |    6 ------
 drivers/pci/quirks.c |    2 --
 3 files changed, 15 deletions(-)

Index: linux-mm/drivers/pci/msi.c
===================================================================
--- linux-mm.orig/drivers/pci/msi.c	2006-06-20 22:03:31.000000000 -0400
+++ linux-mm/drivers/pci/msi.c	2006-06-20 22:03:32.000000000 -0400
@@ -352,13 +352,6 @@
 	if (!status)
 		return status;
 
-	if (pci_msi_quirk) {
-		pci_msi_enable = 0;
-		printk(KERN_WARNING "PCI: MSI quirk detected. MSI disabled.\n");
-		status = -EINVAL;
-		return status;
-	}
-
 	status = msi_arch_init();
 	if (status < 0) {
 		pci_msi_enable = 0;
Index: linux-mm/drivers/pci/pci.h
===================================================================
--- linux-mm.orig/drivers/pci/pci.h	2006-06-20 22:02:00.000000000 -0400
+++ linux-mm/drivers/pci/pci.h	2006-06-20 22:03:32.000000000 -0400
@@ -42,12 +42,6 @@
 /* Lock for read/write access to pci device and bus lists */
 extern struct rw_semaphore pci_bus_sem;
 
-#ifdef CONFIG_X86_IO_APIC
-extern int pci_msi_quirk;
-#else
-#define pci_msi_quirk 0
-#endif
-
 #ifdef CONFIG_PCI_MSI
 void disable_msi_mode(struct pci_dev *dev, int pos, int type);
 void pci_no_msi(void);
Index: linux-mm/drivers/pci/quirks.c
===================================================================
--- linux-mm.orig/drivers/pci/quirks.c	2006-06-20 22:03:30.000000000 -0400
+++ linux-mm/drivers/pci/quirks.c	2006-06-20 22:03:32.000000000 -0400
@@ -576,8 +576,6 @@
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI,	PCI_ANY_ID,			quirk_ioapic_rmw );
 
-int pci_msi_quirk;
-
 #define AMD8131_revA0        0x01
 #define AMD8131_revB0        0x11
 #define AMD8131_MISC         0x40

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 3/6 v4] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality
  2006-06-21  2:32 ` [PATCH 3/6] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality Brice Goglin
@ 2006-06-22 13:56   ` Brice Goglin
  0 siblings, 0 replies; 8+ messages in thread
From: Brice Goglin @ 2006-06-22 13:56 UTC (permalink / raw)
  To: linux-pci; +Cc: linux-kernel, Dave Olson

[PATCH 3/6] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality

Introduce msi_ht_cap_enabled() to check the MSI capability in the
Hypertransport configuration space.
It is used in a generic quirk quirk_msi_ht_cap() to check whether
MSI is enabled on hypertransport chipset, and a nVidia specific quirk
quirk_nvidia_ck804_msi_ht_cap() where two 2 HT MSI mappings have to
be checked.
Both quirks set the PCI_BUS_FLAGS_NO_MSI flags when MSI is disabled.

Signed-off-by: Brice Goglin <brice@myri.com>
---
We now use pci_find_next_capability() to simplify the HT MSI check.
And this patch does not define PCI_DEVICE_ID_NVIDIA_CK804_PCIE anymore
since a patch defining it has been merged meanwhile.

 drivers/pci/quirks.c    |   58 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/pci_ids.h |    1 
 2 files changed, 59 insertions(+)

Index: linux-mm/drivers/pci/quirks.c
===================================================================
--- linux-mm.orig/drivers/pci/quirks.c	2006-06-22 09:38:57.000000000 -0400
+++ linux-mm/drivers/pci/quirks.c	2006-06-22 09:47:46.000000000 -0400
@@ -1603,6 +1603,64 @@
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi);
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCNB_LE,
 			quirk_disable_msi);
+
+/* Go through the list of Hypertransport capabilities and
+ * return 1 if a HT MSI capability is found and enabled */
+static pci_bus_flags_t __devinit msi_ht_cap_enabled(struct pci_dev *dev)
+{
+	u8 pos;
+	for (pos = pci_find_capability(dev, PCI_CAP_ID_HT);
+	     pos;
+	     pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT)) {
+		u32 cap_hdr;
+		/* MSI mapping section according to Hypertransport spec */
+		if (pci_read_config_dword(dev, pos, &cap_hdr) == 0
+		    && (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) {
+			printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n",
+			       pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled");
+			return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */
+		}
+	}
+	return 0;
+}
+
+/* Check the hypertransport MSI mapping to know whether MSI is enabled or not */
+static void __devinit quirk_msi_ht_cap(struct pci_dev *dev)
+{
+	if (!dev->subordinate)
+		return;
+
+	if (!msi_ht_cap_enabled(dev)) {
+		printk(KERN_WARNING "PCI: MSI quirk detected. "
+		       "PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n",
+		       pci_name(dev));
+		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE, quirk_msi_ht_cap);
+
+/* The nVidia CK804 chipset may have 2 HT MSI mappings.
+ * MSI are supported if the MSI capability set in any of these mappings.
+ */
+static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
+{
+	struct pci_dev *pdev;
+
+	if (!dev->subordinate)
+		return;
+
+	/* check HT MSI cap on this chipset and the root one.
+	 * a single one having MSI is enough to be sure that MSI are supported.
+	 */
+	pdev = pci_find_slot(dev->bus->number, 0);
+	if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
+		printk(KERN_WARNING "PCI: MSI quirk detected. "
+		       "PCI_BUS_FLAGS_NO_MSI set for %s subordinate bus.\n",
+		       pci_name(dev));
+		dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MSI;
+	}
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE, quirk_nvidia_ck804_msi_ht_cap);
 #endif /* CONFIG_PCI_MSI */
 
 EXPORT_SYMBOL(pcie_mch_quirk);
Index: linux-mm/include/linux/pci_ids.h
===================================================================
--- linux-mm.orig/include/linux/pci_ids.h	2006-06-21 08:16:06.000000000 -0400
+++ linux-mm/include/linux/pci_ids.h	2006-06-22 09:39:23.000000000 -0400
@@ -1406,6 +1406,7 @@
 #define PCI_DEVICE_ID_SERVERWORKS_LE	  0x0009
 #define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017
 #define PCI_DEVICE_ID_SERVERWORKS_EPB	  0x0103
+#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE	0x0132
 #define PCI_DEVICE_ID_SERVERWORKS_OSB4	  0x0200
 #define PCI_DEVICE_ID_SERVERWORKS_CSB5	  0x0201
 #define PCI_DEVICE_ID_SERVERWORKS_CSB6    0x0203

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2006-06-22 13:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-06-21  2:31 [PATCH 0/6] Improve MSI detection v3 Brice Goglin
2006-06-21  2:31 ` [PATCH 1/6] Merge existing MSI disabling quirks Brice Goglin
2006-06-21  2:32 ` [PATCH 2/6] Rename PCI_CAP_ID_HT_IRQCONF into PCI_CAP_ID_HT Brice Goglin
2006-06-21  2:32 ` [PATCH 3/6] Blacklist PCI-E chipsets depending on Hypertransport MSI capabality Brice Goglin
2006-06-22 13:56   ` [PATCH 3/6 v4] " Brice Goglin
2006-06-21  2:32 ` [PATCH 4/6] Factorize common MSI detection code from pci_enable_msi() and msix() Brice Goglin
2006-06-21  2:32 ` [PATCH 5/6] Stop inheriting bus flags and check root chipset bus flags instead Brice Goglin
2006-06-21  2:33 ` [PATCH 6/6] Drop pci_msi_quirk Brice Goglin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).