diff options
-rw-r--r-- | arch/ia64/sn/include/xtalk/hubdev.h | 6 | ||||
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 33 | ||||
-rw-r--r-- | arch/ia64/sn/pci/pcibr/pcibr_provider.c | 11 | ||||
-rw-r--r-- | arch/ia64/sn/pci/tioca_provider.c | 5 | ||||
-rw-r--r-- | include/asm-ia64/sn/pcibus_provider_defs.h | 3 |
5 files changed, 43 insertions, 15 deletions
diff --git a/arch/ia64/sn/include/xtalk/hubdev.h b/arch/ia64/sn/include/xtalk/hubdev.h index 580a1c0403a7..ca4e250cdf27 100644 --- a/arch/ia64/sn/include/xtalk/hubdev.h +++ b/arch/ia64/sn/include/xtalk/hubdev.h | |||
@@ -34,7 +34,8 @@ struct sn_flush_device_list { | |||
34 | unsigned long sfdl_force_int_addr; | 34 | unsigned long sfdl_force_int_addr; |
35 | unsigned long sfdl_flush_value; | 35 | unsigned long sfdl_flush_value; |
36 | volatile unsigned long *sfdl_flush_addr; | 36 | volatile unsigned long *sfdl_flush_addr; |
37 | uint64_t sfdl_persistent_busnum; | 37 | uint32_t sfdl_persistent_busnum; |
38 | uint32_t sfdl_persistent_segment; | ||
38 | struct pcibus_info *sfdl_pcibus_info; | 39 | struct pcibus_info *sfdl_pcibus_info; |
39 | spinlock_t sfdl_flush_lock; | 40 | spinlock_t sfdl_flush_lock; |
40 | }; | 41 | }; |
@@ -58,7 +59,8 @@ struct hubdev_info { | |||
58 | 59 | ||
59 | void *hdi_nodepda; | 60 | void *hdi_nodepda; |
60 | void *hdi_node_vertex; | 61 | void *hdi_node_vertex; |
61 | void *hdi_xtalk_vertex; | 62 | uint32_t max_segment_number; |
63 | uint32_t max_pcibus_number; | ||
62 | }; | 64 | }; |
63 | 65 | ||
64 | extern void hubdev_init_node(nodepda_t *, cnodeid_t); | 66 | extern void hubdev_init_node(nodepda_t *, cnodeid_t); |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index a6649baf629a..829ea7985017 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -44,6 +44,9 @@ int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */ | |||
44 | 44 | ||
45 | struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ | 45 | struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ |
46 | 46 | ||
47 | static int max_segment_number = 0; /* Default highest segment number */ | ||
48 | static int max_pcibus_number = 255; /* Default highest pci bus number */ | ||
49 | |||
47 | /* | 50 | /* |
48 | * Hooks and struct for unsupported pci providers | 51 | * Hooks and struct for unsupported pci providers |
49 | */ | 52 | */ |
@@ -157,13 +160,28 @@ static void sn_fixup_ionodes(void) | |||
157 | uint64_t nasid; | 160 | uint64_t nasid; |
158 | int i, widget; | 161 | int i, widget; |
159 | 162 | ||
163 | /* | ||
164 | * Get SGI Specific HUB chipset information. | ||
165 | * Inform Prom that this kernel can support domain bus numbering. | ||
166 | */ | ||
160 | for (i = 0; i < numionodes; i++) { | 167 | for (i = 0; i < numionodes; i++) { |
161 | hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); | 168 | hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); |
162 | nasid = cnodeid_to_nasid(i); | 169 | nasid = cnodeid_to_nasid(i); |
170 | hubdev->max_segment_number = 0xffffffff; | ||
171 | hubdev->max_pcibus_number = 0xff; | ||
163 | status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev)); | 172 | status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev)); |
164 | if (status) | 173 | if (status) |
165 | continue; | 174 | continue; |
166 | 175 | ||
176 | /* Save the largest Domain and pcibus numbers found. */ | ||
177 | if (hubdev->max_segment_number) { | ||
178 | /* | ||
179 | * Dealing with a Prom that supports segments. | ||
180 | */ | ||
181 | max_segment_number = hubdev->max_segment_number; | ||
182 | max_pcibus_number = hubdev->max_pcibus_number; | ||
183 | } | ||
184 | |||
167 | /* Attach the error interrupt handlers */ | 185 | /* Attach the error interrupt handlers */ |
168 | if (nasid & 1) | 186 | if (nasid & 1) |
169 | ice_error_init(hubdev); | 187 | ice_error_init(hubdev); |
@@ -229,7 +247,7 @@ void sn_pci_unfixup_slot(struct pci_dev *dev) | |||
229 | void sn_pci_fixup_slot(struct pci_dev *dev) | 247 | void sn_pci_fixup_slot(struct pci_dev *dev) |
230 | { | 248 | { |
231 | int idx; | 249 | int idx; |
232 | int segment = 0; | 250 | int segment = pci_domain_nr(dev->bus); |
233 | int status = 0; | 251 | int status = 0; |
234 | struct pcibus_bussoft *bs; | 252 | struct pcibus_bussoft *bs; |
235 | struct pci_bus *host_pci_bus; | 253 | struct pci_bus *host_pci_bus; |
@@ -282,9 +300,9 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
282 | * PCI host_pci_dev struct and set up host bus linkages | 300 | * PCI host_pci_dev struct and set up host bus linkages |
283 | */ | 301 | */ |
284 | 302 | ||
285 | bus_no = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32; | 303 | bus_no = (SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32) & 0xff; |
286 | devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff; | 304 | devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff; |
287 | host_pci_bus = pci_find_bus(pci_domain_nr(dev->bus), bus_no); | 305 | host_pci_bus = pci_find_bus(segment, bus_no); |
288 | host_pci_dev = pci_get_slot(host_pci_bus, devfn); | 306 | host_pci_dev = pci_get_slot(host_pci_bus, devfn); |
289 | 307 | ||
290 | SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev; | 308 | SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev; |
@@ -332,6 +350,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
332 | prom_bussoft_ptr = __va(prom_bussoft_ptr); | 350 | prom_bussoft_ptr = __va(prom_bussoft_ptr); |
333 | 351 | ||
334 | controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); | 352 | controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); |
353 | controller->segment = segment; | ||
335 | if (!controller) | 354 | if (!controller) |
336 | BUG(); | 355 | BUG(); |
337 | 356 | ||
@@ -387,7 +406,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
387 | if (controller->node >= num_online_nodes()) { | 406 | if (controller->node >= num_online_nodes()) { |
388 | struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); | 407 | struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); |
389 | 408 | ||
390 | printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu" | 409 | printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" |
391 | "L_IO=%lx L_MEM=%lx BASE=%lx\n", | 410 | "L_IO=%lx L_MEM=%lx BASE=%lx\n", |
392 | b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, | 411 | b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, |
393 | b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); | 412 | b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); |
@@ -442,6 +461,7 @@ sn_sysdata_free_start: | |||
442 | static int __init sn_pci_init(void) | 461 | static int __init sn_pci_init(void) |
443 | { | 462 | { |
444 | int i = 0; | 463 | int i = 0; |
464 | int j = 0; | ||
445 | struct pci_dev *pci_dev = NULL; | 465 | struct pci_dev *pci_dev = NULL; |
446 | extern void sn_init_cpei_timer(void); | 466 | extern void sn_init_cpei_timer(void); |
447 | #ifdef CONFIG_PROC_FS | 467 | #ifdef CONFIG_PROC_FS |
@@ -476,8 +496,9 @@ static int __init sn_pci_init(void) | |||
476 | #endif | 496 | #endif |
477 | 497 | ||
478 | /* busses are not known yet ... */ | 498 | /* busses are not known yet ... */ |
479 | for (i = 0; i < PCI_BUSES_TO_SCAN; i++) | 499 | for (i = 0; i <= max_segment_number; i++) |
480 | sn_pci_controller_fixup(0, i, NULL); | 500 | for (j = 0; j <= max_pcibus_number; j++) |
501 | sn_pci_controller_fixup(i, j, NULL); | ||
481 | 502 | ||
482 | /* | 503 | /* |
483 | * Generic Linux PCI Layer has created the pci_bus and pci_dev | 504 | * Generic Linux PCI Layer has created the pci_bus and pci_dev |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index b95e928636a1..dfaf01e5be80 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
@@ -60,7 +60,7 @@ static int sal_pcibr_error_interrupt(struct pcibus_info *soft) | |||
60 | ret_stuff.status = 0; | 60 | ret_stuff.status = 0; |
61 | ret_stuff.v0 = 0; | 61 | ret_stuff.v0 = 0; |
62 | 62 | ||
63 | segment = 0; | 63 | segment = soft->pbi_buscommon.bs_persist_segment; |
64 | busnum = soft->pbi_buscommon.bs_persist_busnum; | 64 | busnum = soft->pbi_buscommon.bs_persist_busnum; |
65 | SAL_CALL_NOLOCK(ret_stuff, | 65 | SAL_CALL_NOLOCK(ret_stuff, |
66 | (u64) SN_SAL_IOIF_ERROR_INTERRUPT, | 66 | (u64) SN_SAL_IOIF_ERROR_INTERRUPT, |
@@ -142,9 +142,12 @@ pcibr_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
142 | j++, sn_flush_device_list++) { | 142 | j++, sn_flush_device_list++) { |
143 | if (sn_flush_device_list->sfdl_slot == -1) | 143 | if (sn_flush_device_list->sfdl_slot == -1) |
144 | continue; | 144 | continue; |
145 | if (sn_flush_device_list-> | 145 | if ((sn_flush_device_list-> |
146 | sfdl_persistent_busnum == | 146 | sfdl_persistent_segment == |
147 | soft->pbi_buscommon.bs_persist_busnum) | 147 | soft->pbi_buscommon.bs_persist_segment) && |
148 | (sn_flush_device_list-> | ||
149 | sfdl_persistent_busnum == | ||
150 | soft->pbi_buscommon.bs_persist_busnum)) | ||
148 | sn_flush_device_list->sfdl_pcibus_info = | 151 | sn_flush_device_list->sfdl_pcibus_info = |
149 | soft; | 152 | soft; |
150 | } | 153 | } |
diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 5d76a7581465..2fef7c10d6e5 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c | |||
@@ -559,7 +559,7 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) | |||
559 | ret_stuff.status = 0; | 559 | ret_stuff.status = 0; |
560 | ret_stuff.v0 = 0; | 560 | ret_stuff.v0 = 0; |
561 | 561 | ||
562 | segment = 0; | 562 | segment = soft->ca_common.bs_persist_segment; |
563 | busnum = soft->ca_common.bs_persist_busnum; | 563 | busnum = soft->ca_common.bs_persist_busnum; |
564 | 564 | ||
565 | SAL_CALL_NOLOCK(ret_stuff, | 565 | SAL_CALL_NOLOCK(ret_stuff, |
@@ -622,7 +622,8 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont | |||
622 | nasid_to_cnodeid(tioca_common->ca_closest_nasid); | 622 | nasid_to_cnodeid(tioca_common->ca_closest_nasid); |
623 | tioca_common->ca_kernel_private = (uint64_t) tioca_kern; | 623 | tioca_common->ca_kernel_private = (uint64_t) tioca_kern; |
624 | 624 | ||
625 | bus = pci_find_bus(0, tioca_common->ca_common.bs_persist_busnum); | 625 | bus = pci_find_bus(tioca_common->ca_common.bs_persist_segment, |
626 | tioca_common->ca_common.bs_persist_busnum); | ||
626 | BUG_ON(!bus); | 627 | BUG_ON(!bus); |
627 | tioca_kern->ca_devices = &bus->devices; | 628 | tioca_kern->ca_devices = &bus->devices; |
628 | 629 | ||
diff --git a/include/asm-ia64/sn/pcibus_provider_defs.h b/include/asm-ia64/sn/pcibus_provider_defs.h index 976f5eff0539..b01b21eec55a 100644 --- a/include/asm-ia64/sn/pcibus_provider_defs.h +++ b/include/asm-ia64/sn/pcibus_provider_defs.h | |||
@@ -30,7 +30,8 @@ | |||
30 | struct pcibus_bussoft { | 30 | struct pcibus_bussoft { |
31 | uint32_t bs_asic_type; /* chipset type */ | 31 | uint32_t bs_asic_type; /* chipset type */ |
32 | uint32_t bs_xid; /* xwidget id */ | 32 | uint32_t bs_xid; /* xwidget id */ |
33 | uint64_t bs_persist_busnum; /* Persistent Bus Number */ | 33 | uint32_t bs_persist_busnum; /* Persistent Bus Number */ |
34 | uint32_t bs_persist_segment; /* Segment Number */ | ||
34 | uint64_t bs_legacy_io; /* legacy io pio addr */ | 35 | uint64_t bs_legacy_io; /* legacy io pio addr */ |
35 | uint64_t bs_legacy_mem; /* legacy mem pio addr */ | 36 | uint64_t bs_legacy_mem; /* legacy mem pio addr */ |
36 | uint64_t bs_base; /* widget base */ | 37 | uint64_t bs_base; /* widget base */ |