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[]; |
