[PATCH] x86-64: Use ACPI PXM to parse PCI<->node assignments

Since this is shared code I had to implement it for i386 too

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/arch/i386/kernel/srat.c b/arch/i386/kernel/srat.c
index 7b3b27d..516bf56 100644
--- a/arch/i386/kernel/srat.c
+++ b/arch/i386/kernel/srat.c
@@ -213,12 +213,18 @@
 		node_end_pfn[nid] = memory_chunk->end_pfn;
 }
 
+static u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */
+
+int pxm_to_node(int pxm)
+{
+	return pxm_to_nid_map[pxm];
+}
+
 /* Parse the ACPI Static Resource Affinity Table */
 static int __init acpi20_parse_srat(struct acpi_table_srat *sratp)
 {
 	u8 *start, *end, *p;
 	int i, j, nid;
-	u8 pxm_to_nid_map[MAX_PXM_DOMAINS];/* _PXM to logical node ID map */
 	u8 nid_to_pxm_map[MAX_NUMNODES];/* logical node ID to _PXM map */
 
 	start = (u8 *)(&(sratp->reserved) + 1);	/* skip header */
diff --git a/arch/i386/pci/acpi.c b/arch/i386/pci/acpi.c
index 42913f4..2941674 100644
--- a/arch/i386/pci/acpi.c
+++ b/arch/i386/pci/acpi.c
@@ -3,16 +3,31 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <asm/hw_irq.h>
+#include <asm/numa.h>
 #include "pci.h"
 
 struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int domain, int busnum)
 {
+	struct pci_bus *bus;
+
 	if (domain != 0) {
 		printk(KERN_WARNING "PCI: Multiple domains not supported\n");
 		return NULL;
 	}
 
-	return pcibios_scan_root(busnum);
+	bus = pcibios_scan_root(busnum);
+#ifdef CONFIG_ACPI_NUMA
+	if (bus != NULL) {
+		int pxm = acpi_get_pxm(device->handle);
+		if (pxm >= 0) {
+			bus->sysdata = (void *)(unsigned long)pxm_to_node(pxm);
+			printk("bus %d -> pxm %d -> node %ld\n",
+				busnum, pxm, (long)(bus->sysdata));
+		}
+	}
+#endif
+	
+	return bus;
 }
 
 extern int pci_routeirq;
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 312ecc9..1164252 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -46,8 +46,6 @@
 int apic_version [MAX_APICS];
 unsigned char mp_bus_id_to_type [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
 int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { [0 ... MAX_MP_BUSSES-1] = -1 };
-unsigned char pci_bus_to_node [256];
-EXPORT_SYMBOL(pci_bus_to_node);
 
 static int mp_current_pci_id = 0;
 /* I/O APIC entries */
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 92f6ec7..db6b073 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -25,6 +25,13 @@
 static struct node nodes[MAX_NUMNODES] __initdata;
 static __u8  pxm2node[256] = { [0 ... 255] = 0xff };
 
+int pxm_to_node(int pxm)
+{
+	if ((unsigned)pxm >= 256)
+		return 0;
+	return pxm2node[pxm];
+}
+
 static __init int setup_node(int pxm)
 {
 	unsigned node = pxm2node[pxm];
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c
index d80c323..3acf60d 100644
--- a/arch/x86_64/pci/k8-bus.c
+++ b/arch/x86_64/pci/k8-bus.c
@@ -58,10 +58,16 @@
 				for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus);
 				     j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus);
 				     j++) { 
-					int node = NODE_ID(nid);
+					struct pci_bus *bus;
+					long node = NODE_ID(nid);
+					/* Algorithm a bit dumb, but
+ 					   it shouldn't matter here */
+					bus = pci_find_bus(0, j);
+					if (!bus)
+						continue;
 					if (!node_online(node))
 						node = 0;
-					pci_bus_to_node[j] = node;
+					bus->sysdata = (void *)node;
 				}		
 			}
 		}