lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Sun, 25 Nov 2007 11:21:48 +0800
From:	"peerchen" <peerchen@...il.com>
To:	"linux-kernel" <linux-kernel@...r.kernel.org>
Cc:	"akpm" <akpm@...ux-foundation.org>, "pchen" <pchen@...dia.com>,
	"acurrid" <acurrid@...dia.com>
Subject: [PATCH 1/2] msi: set 'En' bit of MSI Mapping Capability on HT platform

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@...dia.com>
Signed-off-by: Peer Chen <pchen@...dia.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);
-

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists