diff options
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 20 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pci_dma.c | 16 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_provider.c | 10 | ||||
-rw-r--r-- | arch/ia64/sn/pci/tioca_provider.c | 4 | ||||
-rw-r--r-- | include/asm-ia64/sn/pcibr_provider.h | 2 | ||||
-rw-r--r-- | include/asm-ia64/sn/pcibus_provider_defs.h | 3 |
6 files changed, 46 insertions, 9 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index a67f39e448cb..a6649baf629a 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) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | static void * | 63 | static void * |
64 | sn_default_pci_bus_fixup(struct pcibus_bussoft *soft) | 64 | sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) |
65 | { | 65 | { |
66 | return NULL; | 66 | return NULL; |
67 | } | 67 | } |
@@ -362,7 +362,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
362 | 362 | ||
363 | provider_soft = NULL; | 363 | provider_soft = NULL; |
364 | if (provider->bus_fixup) | 364 | if (provider->bus_fixup) |
365 | provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr); | 365 | provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); |
366 | 366 | ||
367 | if (provider_soft == NULL) | 367 | if (provider_soft == NULL) |
368 | return; /* fixup failed or not applicable */ | 368 | return; /* fixup failed or not applicable */ |
@@ -380,6 +380,22 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
380 | SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = | 380 | SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = |
381 | &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); | 381 | &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); |
382 | 382 | ||
383 | /* | ||
384 | * If the node information we obtained during the fixup phase is invalid | ||
385 | * then set controller->node to -1 (undetermined) | ||
386 | */ | ||
387 | if (controller->node >= num_online_nodes()) { | ||
388 | struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); | ||
389 | |||
390 | printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu" | ||
391 | "L_IO=%lx L_MEM=%lx BASE=%lx\n", | ||
392 | b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, | ||
393 | b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); | ||
394 | printk(KERN_WARNING "on node %d but only %d nodes online." | ||
395 | "Association set to undetermined.\n", | ||
396 | controller->node, num_online_nodes()); | ||
397 | controller->node = -1; | ||
398 | } | ||
383 | return; | 399 | return; |
384 | 400 | ||
385 | error_return: | 401 | error_return: |
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 | ||
87 | void * | 87 | void * |
88 | pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft) | 88 | pcibr_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 | */ |
583 | static void * | 583 | static void * |
584 | tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) | 584 | tioca_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 | ||
diff --git a/include/asm-ia64/sn/pcibr_provider.h b/include/asm-ia64/sn/pcibr_provider.h index f9b8d2164007..2b42d9ece26b 100644 --- a/include/asm-ia64/sn/pcibr_provider.h +++ b/include/asm-ia64/sn/pcibr_provider.h | |||
@@ -128,7 +128,7 @@ pcibr_lock(struct pcibus_info *pcibus_info) | |||
128 | #define pcibr_unlock(pcibus_info, flag) spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag) | 128 | #define pcibr_unlock(pcibus_info, flag) spin_unlock_irqrestore(&pcibus_info->pbi_lock, flag) |
129 | 129 | ||
130 | extern int pcibr_init_provider(void); | 130 | extern int pcibr_init_provider(void); |
131 | extern void *pcibr_bus_fixup(struct pcibus_bussoft *); | 131 | extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *); |
132 | extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t); | 132 | extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t); |
133 | extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t); | 133 | extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t); |
134 | extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int); | 134 | extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int); |
diff --git a/include/asm-ia64/sn/pcibus_provider_defs.h b/include/asm-ia64/sn/pcibus_provider_defs.h index 04e27d5b3820..976f5eff0539 100644 --- a/include/asm-ia64/sn/pcibus_provider_defs.h +++ b/include/asm-ia64/sn/pcibus_provider_defs.h | |||
@@ -37,6 +37,7 @@ struct pcibus_bussoft { | |||
37 | struct xwidget_info *bs_xwidget_info; | 37 | struct xwidget_info *bs_xwidget_info; |
38 | }; | 38 | }; |
39 | 39 | ||
40 | struct pci_controller; | ||
40 | /* | 41 | /* |
41 | * SN pci bus indirection | 42 | * SN pci bus indirection |
42 | */ | 43 | */ |
@@ -45,7 +46,7 @@ struct sn_pcibus_provider { | |||
45 | dma_addr_t (*dma_map)(struct pci_dev *, unsigned long, size_t); | 46 | dma_addr_t (*dma_map)(struct pci_dev *, unsigned long, size_t); |
46 | dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t); | 47 | dma_addr_t (*dma_map_consistent)(struct pci_dev *, unsigned long, size_t); |
47 | void (*dma_unmap)(struct pci_dev *, dma_addr_t, int); | 48 | void (*dma_unmap)(struct pci_dev *, dma_addr_t, int); |
48 | void * (*bus_fixup)(struct pcibus_bussoft *); | 49 | void * (*bus_fixup)(struct pcibus_bussoft *, struct pci_controller *); |
49 | }; | 50 | }; |
50 | 51 | ||
51 | extern struct sn_pcibus_provider *sn_pci_provider[]; | 52 | extern struct sn_pcibus_provider *sn_pci_provider[]; |