aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/sn/pci
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2005-07-12 19:03:00 -0400
committerTony Luck <tony.luck@intel.com>2005-07-12 19:12:55 -0400
commit7c2a6c62c013a4ea57243536fc7f3987e4ba04bc (patch)
tree02e3e1d9888f81110ba85bef531e5c695f6064ce /arch/ia64/sn/pci
parent08357f82d4decc48bbfd39ae30d5fe0754f7f576 (diff)
[IA64] Altix pcibus_to_node implementation
The Altix subarch does not provide node information via ACPI. Instead hooks are used to fixup pci structures. This patch determines the nodes for Altix PCI busses. Remote Bridges: --------------- Altix supports remote I/O nodes without memory or processors but with bridges. The TIOCA type of bridge is an AGP bridge and the PROM provides information about the closest node. That information will be returned by pcibus_to_node. The TIOCP remote bridge type is a PCI bridge but the PROM does not provide a closest node id. pcibus_to_node will return -1 for devices on those bridges meaning that device control structures may be allocated on any node. Safeguard: ---------- Should the fixups result in invalid node information for a pci controller then a warning will be printed and pcibus_to_node will return -1. This patch also fixes the "FIXME" in sn_dma_alloc_coherent. This means that dma_alloc_coherent will now use alloc_pages_node to allocate memory local to the node that the PCI device is connected to. Signed-off-by: Christoph Lameter <clameter@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/sn/pci')
-rw-r--r--arch/ia64/sn/pci/pci_dma.c16
-rw-r--r--arch/ia64/sn/pci/pcibr/pcibr_provider.c10
-rw-r--r--arch/ia64/sn/pci/tioca_provider.c4
3 files changed, 25 insertions, 5 deletions
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index a2f7a88aefbb..0e4b9ad9ef02 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -79,6 +79,7 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
79{ 79{
80 void *cpuaddr; 80 void *cpuaddr;
81 unsigned long phys_addr; 81 unsigned long phys_addr;
82 int node;
82 struct pci_dev *pdev = to_pci_dev(dev); 83 struct pci_dev *pdev = to_pci_dev(dev);
83 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 84 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
84 85
@@ -86,10 +87,19 @@ void *sn_dma_alloc_coherent(struct device *dev, size_t size,
86 87
87 /* 88 /*
88 * Allocate the memory. 89 * Allocate the memory.
89 * FIXME: We should be doing alloc_pages_node for the node closest
90 * to the PCI device.
91 */ 90 */
92 if (!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)))) 91 node = pcibus_to_node(pdev->bus);
92 if (likely(node >=0)) {
93 struct page *p = alloc_pages_node(node, GFP_ATOMIC, get_order(size));
94
95 if (likely(p))
96 cpuaddr = page_address(p);
97 else
98 return NULL;
99 } else
100 cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size));
101
102 if (unlikely(!cpuaddr))
93 return NULL; 103 return NULL;
94 104
95 memset(cpuaddr, 0x0, size); 105 memset(cpuaddr, 0x0, size);
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
index 9813da56d311..b95e928636a1 100644
--- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c
+++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c
@@ -85,7 +85,7 @@ pcibr_error_intr_handler(int irq, void *arg, struct pt_regs *regs)
85} 85}
86 86
87void * 87void *
88pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft) 88pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
89{ 89{
90 int nasid, cnode, j; 90 int nasid, cnode, j;
91 struct hubdev_info *hubdev_info; 91 struct hubdev_info *hubdev_info;
@@ -158,6 +158,14 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft)
158 memset(soft->pbi_int_ate_resource.ate, 0, 158 memset(soft->pbi_int_ate_resource.ate, 0,
159 (soft->pbi_int_ate_size * sizeof(uint64_t))); 159 (soft->pbi_int_ate_size * sizeof(uint64_t)));
160 160
161 if (prom_bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP)
162 /*
163 * TIO PCI Bridge with no closest node information.
164 * FIXME: Find another way to determine the closest node
165 */
166 controller->node = -1;
167 else
168 controller->node = cnode;
161 return soft; 169 return soft;
162} 170}
163 171
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c
index 51cc4e63092c..5d76a7581465 100644
--- a/arch/ia64/sn/pci/tioca_provider.c
+++ b/arch/ia64/sn/pci/tioca_provider.c
@@ -581,7 +581,7 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt)
581 * the caller. 581 * the caller.
582 */ 582 */
583static void * 583static void *
584tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) 584tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *controller)
585{ 585{
586 struct tioca_common *tioca_common; 586 struct tioca_common *tioca_common;
587 struct tioca_kernel *tioca_kern; 587 struct tioca_kernel *tioca_kern;
@@ -646,6 +646,8 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft)
646 __FUNCTION__, SGI_TIOCA_ERROR, 646 __FUNCTION__, SGI_TIOCA_ERROR,
647 (int)tioca_common->ca_common.bs_persist_busnum); 647 (int)tioca_common->ca_common.bs_persist_busnum);
648 648
649 /* Setup locality information */
650 controller->node = tioca_kern->ca_closest_node;
649 return tioca_common; 651 return tioca_common;
650} 652}
651 653