===== arch/ia64/sn/io/machvec/pci_dma.c 1.30 vs edited ===== --- 1.30/arch/ia64/sn/io/machvec/pci_dma.c 2004-03-26 06:33:08 -08:00 +++ edited/arch/ia64/sn/io/machvec/pci_dma.c 2004-10-12 13:33:33 -07:00 @@ -28,6 +28,36 @@ extern void * busnum_to_atedmamaps[]; /** + * pci_to_node - find the node a given PCI device is attached to + * @dev: PCI dev to query + * + * Extract the NASID from the physical resource addr and use it + * to get the logical node number. Return 0 if we couldn't find + * one. This should be ok until node 0 is offline at boot or + * removed later. + */ +static short pci_to_node(struct pci_dev *dev) +{ + unsigned long paddr; + int node; + + /* FIXME: use PCI nodemask when it's there */ + if (!dev->resource[0].start) { + printk("PCI device has no resources!\n"); + return 0; /* valid until node hot swap */ + } + + paddr = pci_resource_start(dev, 0) & ~__IA64_UNCACHED_OFFSET; + /* + * If the nodeid is invalid (as might happen with headless nodes) + * allocate from the current node. + */ + if ((node = nasid_to_cnodeid(NASID_GET(paddr))) >= numnodes) + return local_node_data->node; + return node; +} + +/** * get_free_pciio_dmamap - find and allocate an ATE * @pci_bus: PCI bus to get an entry for * @@ -118,6 +148,7 @@ void * sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle) { + struct page *cpupage; void *cpuaddr; vertex_hdl_t vhdl; struct sn_device_sysdata *device_sysdata; @@ -130,13 +161,12 @@ device_sysdata = SN_DEVICE_SYSDATA(hwdev); vhdl = device_sysdata->vhdl; - /* - * Allocate the memory. - * FIXME: We should be doing alloc_pages_node for the node closest - * to the PCI device. - */ - if (!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size)))) + cpupage = alloc_pages_node(pci_to_node(hwdev), GFP_ATOMIC, + get_order(size)); + if (!cpupage) return NULL; + + cpuaddr = __va(page_to_phys(cpupage)); memset(cpuaddr, 0x0, size);