From: "peerchen" <peerchen@gmail.com>
To: "linux-kernel" <linux-kernel@vger.kernel.org>
Cc: "akpm" <akpm@linux-foundation.org>, "pchen" <pchen@nvidia.com>,
"acurrid" <acurrid@nvidia.com>
Subject: [PATCH 1/2] msi: set 'En' bit of MSI Mapping Capability on HT platform
Date: Sun, 25 Nov 2007 11:21:48 +0800 [thread overview]
Message-ID: <200711251121445151346@gmail.com> (raw)
According to the HyperTransport spec, 'En' indicate if the MSI Mapping is active. So it should be set when enable the MSI.
The patch base on kernel 2.6.24-rc3
Signed-off-by: Andy Currid <acurrid@nvidia.com>
Signed-off-by: Peer Chen <pchen@nvidia.com>
---
--- linux-2.6.24-rc3/drivers/pci/msi.c.orig 2007-11-23 17:28:45.000000000 -0500
+++ linux-2.6.24-rc3/drivers/pci/msi.c 2007-11-23 17:50:59.000000000 -0500
@@ -20,6 +20,8 @@
#include <asm/errno.h>
#include <asm/io.h>
+#include <asm/k8.h>
+
#include "pci.h"
#include "msi.h"
@@ -290,6 +292,99 @@ void pci_restore_msi_state(struct pci_de
}
#endif /* CONFIG_PM */
+/*
+ * pci_enable_msi_ht_cap - Set the HT MSI mapping capability En bit of
+ * a device.
+ *
+ * @dev: pointer to the pci_dev data structure of MSI device function
+ */
+
+static int pci_enable_msi_ht_cap(struct pci_dev *dev)
+{
+ int pos;
+ u8 flags;
+
+ if ((pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING)) != 0)
+ {
+ pci_read_config_byte(dev, pos + HT_MSI_FLAGS, &flags);
+ pci_write_config_byte(dev, pos + HT_MSI_FLAGS,
+ flags | HT_MSI_FLAGS_ENABLE);
+
+ printk(KERN_INFO "PCI: %s: enabled HT MSI mapping\n", pci_name(dev));
+ }
+
+ return pos;
+}
+
+/**
+ * pci_check_msi_ht_cap - check for and enable the MSI mapping capability En bit
+ * of devices or upstream bridge on HT-base system.
+ * @dev: pointer to the pci_dev data structure of MSI device function
+ *
+ * Search if device support ht MSI mapping capability on HT-base
+ * platform, if yes, enable the En bit. If device can't support MSI mapping,
+ * search the the upstream bridge for that capability, enable En bit find it,
+ * otherwise disable the MSI function if device and upstream bridge can't
+ * support MSI mapping capability.
+ **/
+
+static int pci_check_msi_ht_cap(struct pci_dev *dev)
+{
+ struct pci_dev *bridge_dev;
+
+ if (num_k8_northbridges != 0) { /* If the system is the HT-base */
+
+ /* Check for upstream NVIDIA host bridges */
+
+ if (((bridge_dev = pci_find_slot(0, 0)) != NULL) &&
+ (bridge_dev->vendor == PCI_VENDOR_ID_NVIDIA)) {
+ switch (bridge_dev->device) {
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC0:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC1:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC2:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC3:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC4:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC5:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC6:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_C51_MEMC7:
+ case PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_MEMC:
+
+ pci_enable_msi_ht_cap(bridge_dev);
+
+ bridge_dev = NULL;
+ while ((bridge_dev = pci_get_device(PCI_VENDOR_ID_NVIDIA,
+ PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_MEMC, bridge_dev))
+ != NULL) {
+ pci_enable_msi_ht_cap(bridge_dev);
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+
+
+ if (pci_enable_msi_ht_cap(dev) != 0) {
+ return 0;
+ } else {
+ /* Get upstream bridge device handle */
+
+ bridge_dev = dev->bus->self;
+ while(bridge_dev != 0) {
+ if (pci_enable_msi_ht_cap(bridge_dev) != 0) {
+ return 0;
+ } else
+ bridge_dev = bridge_dev->bus->self;
+ }
+
+ return 1;
+ }
+ }
+ return 0;
+}
+
/**
* msi_capability_init - configure device's MSI capability structure
* @dev: pointer to the pci_dev data structure of MSI device function
@@ -510,6 +605,10 @@ int pci_enable_msi(struct pci_dev* dev)
status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI);
if (status)
return status;
+
+ status = pci_check_msi_ht_cap(dev);
+ if(status)
+ return status;
WARN_ON(!!dev->msi_enabled);
@@ -606,6 +705,10 @@ int pci_enable_msix(struct pci_dev* dev,
if (status)
return status;
+ status = pci_check_msi_ht_cap(dev);
+ if(status)
+ return status;
+
pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
pci_read_config_word(dev, msi_control_reg(pos), &control);
nr_entries = multi_msix_capable(control);
-
next reply other threads:[~2007-11-25 3:22 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-11-25 3:21 peerchen [this message]
2007-11-25 10:21 ` [PATCH 1/2] msi: set 'En' bit of MSI Mapping Capability on HT platform Prakash Punnoor
2007-11-27 8:00 ` Andrew Morton
2007-11-26 9:43 ` Sébastien Dugué
2007-11-27 8:13 ` Andrew Morton
[not found] <fa.o8FrHkCTygSL3HgQ8yHeTr2D3tI@ifi.uio.no>
2007-11-25 18:33 ` Robert Hancock
2007-11-26 4:01 ` Peer Chen
2007-11-26 5:14 ` Andy Currid
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200711251121445151346@gmail.com \
--to=peerchen@gmail.com \
--cc=acurrid@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pchen@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.