diff options
author | Christoph Lameter <clameter@sgi.com> | 2005-07-12 16:03:00 -0700 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-07-12 16:12:55 -0700 |
commit | 7c2a6c62c013a4ea57243536fc7f3987e4ba04bc (patch) | |
tree | 02e3e1d9888f81110ba85bef531e5c695f6064ce /arch/ia64/sn/kernel | |
parent | 08357f82d4decc48bbfd39ae30d5fe0754f7f576 (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/kernel')
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index a67f39e448c..a6649baf629 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -61,7 +61,7 @@ sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) } static void * -sn_default_pci_bus_fixup(struct pcibus_bussoft *soft) +sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) { return NULL; } @@ -362,7 +362,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) provider_soft = NULL; if (provider->bus_fixup) - provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr); + provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); if (provider_soft == NULL) return; /* fixup failed or not applicable */ @@ -380,6 +380,22 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); + /* + * If the node information we obtained during the fixup phase is invalid + * then set controller->node to -1 (undetermined) + */ + if (controller->node >= num_online_nodes()) { + struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); + + printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu" + "L_IO=%lx L_MEM=%lx BASE=%lx\n", + b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, + b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); + printk(KERN_WARNING "on node %d but only %d nodes online." + "Association set to undetermined.\n", + controller->node, num_online_nodes()); + controller->node = -1; + } return; error_return: |