diff options
Diffstat (limited to 'arch/ia64/sn/kernel/io_init.c')
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 414cdf2e3c96..4564ed0b5ff3 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/sn/simulator.h> | 18 | #include <asm/sn/simulator.h> |
19 | #include <asm/sn/sn_sal.h> | 19 | #include <asm/sn/sn_sal.h> |
20 | #include <asm/sn/tioca_provider.h> | 20 | #include <asm/sn/tioca_provider.h> |
21 | #include <asm/sn/tioce_provider.h> | ||
21 | #include "xtalk/hubdev.h" | 22 | #include "xtalk/hubdev.h" |
22 | #include "xtalk/xwidgetdev.h" | 23 | #include "xtalk/xwidgetdev.h" |
23 | 24 | ||
@@ -44,6 +45,9 @@ int sn_ioif_inited = 0; /* SN I/O infrastructure initialized? */ | |||
44 | 45 | ||
45 | struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ | 46 | struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ |
46 | 47 | ||
48 | static int max_segment_number = 0; /* Default highest segment number */ | ||
49 | static int max_pcibus_number = 255; /* Default highest pci bus number */ | ||
50 | |||
47 | /* | 51 | /* |
48 | * Hooks and struct for unsupported pci providers | 52 | * Hooks and struct for unsupported pci providers |
49 | */ | 53 | */ |
@@ -157,13 +161,28 @@ static void sn_fixup_ionodes(void) | |||
157 | uint64_t nasid; | 161 | uint64_t nasid; |
158 | int i, widget; | 162 | int i, widget; |
159 | 163 | ||
164 | /* | ||
165 | * Get SGI Specific HUB chipset information. | ||
166 | * Inform Prom that this kernel can support domain bus numbering. | ||
167 | */ | ||
160 | for (i = 0; i < numionodes; i++) { | 168 | for (i = 0; i < numionodes; i++) { |
161 | hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); | 169 | hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); |
162 | nasid = cnodeid_to_nasid(i); | 170 | nasid = cnodeid_to_nasid(i); |
171 | hubdev->max_segment_number = 0xffffffff; | ||
172 | hubdev->max_pcibus_number = 0xff; | ||
163 | status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev)); | 173 | status = sal_get_hubdev_info(nasid, (uint64_t) __pa(hubdev)); |
164 | if (status) | 174 | if (status) |
165 | continue; | 175 | continue; |
166 | 176 | ||
177 | /* Save the largest Domain and pcibus numbers found. */ | ||
178 | if (hubdev->max_segment_number) { | ||
179 | /* | ||
180 | * Dealing with a Prom that supports segments. | ||
181 | */ | ||
182 | max_segment_number = hubdev->max_segment_number; | ||
183 | max_pcibus_number = hubdev->max_pcibus_number; | ||
184 | } | ||
185 | |||
167 | /* Attach the error interrupt handlers */ | 186 | /* Attach the error interrupt handlers */ |
168 | if (nasid & 1) | 187 | if (nasid & 1) |
169 | ice_error_init(hubdev); | 188 | ice_error_init(hubdev); |
@@ -230,7 +249,7 @@ void sn_pci_unfixup_slot(struct pci_dev *dev) | |||
230 | void sn_pci_fixup_slot(struct pci_dev *dev) | 249 | void sn_pci_fixup_slot(struct pci_dev *dev) |
231 | { | 250 | { |
232 | int idx; | 251 | int idx; |
233 | int segment = 0; | 252 | int segment = pci_domain_nr(dev->bus); |
234 | int status = 0; | 253 | int status = 0; |
235 | struct pcibus_bussoft *bs; | 254 | struct pcibus_bussoft *bs; |
236 | struct pci_bus *host_pci_bus; | 255 | struct pci_bus *host_pci_bus; |
@@ -283,9 +302,9 @@ void sn_pci_fixup_slot(struct pci_dev *dev) | |||
283 | * PCI host_pci_dev struct and set up host bus linkages | 302 | * PCI host_pci_dev struct and set up host bus linkages |
284 | */ | 303 | */ |
285 | 304 | ||
286 | bus_no = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32; | 305 | bus_no = (SN_PCIDEV_INFO(dev)->pdi_slot_host_handle >> 32) & 0xff; |
287 | devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff; | 306 | devfn = SN_PCIDEV_INFO(dev)->pdi_slot_host_handle & 0xffffffff; |
288 | host_pci_bus = pci_find_bus(pci_domain_nr(dev->bus), bus_no); | 307 | host_pci_bus = pci_find_bus(segment, bus_no); |
289 | host_pci_dev = pci_get_slot(host_pci_bus, devfn); | 308 | host_pci_dev = pci_get_slot(host_pci_bus, devfn); |
290 | 309 | ||
291 | SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev; | 310 | SN_PCIDEV_INFO(dev)->host_pci_dev = host_pci_dev; |
@@ -333,6 +352,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
333 | prom_bussoft_ptr = __va(prom_bussoft_ptr); | 352 | prom_bussoft_ptr = __va(prom_bussoft_ptr); |
334 | 353 | ||
335 | controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); | 354 | controller = kcalloc(1,sizeof(struct pci_controller), GFP_KERNEL); |
355 | controller->segment = segment; | ||
336 | if (!controller) | 356 | if (!controller) |
337 | BUG(); | 357 | BUG(); |
338 | 358 | ||
@@ -390,7 +410,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
390 | if (controller->node >= num_online_nodes()) { | 410 | if (controller->node >= num_online_nodes()) { |
391 | struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); | 411 | struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); |
392 | 412 | ||
393 | printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%lu" | 413 | printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" |
394 | "L_IO=%lx L_MEM=%lx BASE=%lx\n", | 414 | "L_IO=%lx L_MEM=%lx BASE=%lx\n", |
395 | b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, | 415 | b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, |
396 | b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); | 416 | b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); |
@@ -445,6 +465,7 @@ sn_sysdata_free_start: | |||
445 | static int __init sn_pci_init(void) | 465 | static int __init sn_pci_init(void) |
446 | { | 466 | { |
447 | int i = 0; | 467 | int i = 0; |
468 | int j = 0; | ||
448 | struct pci_dev *pci_dev = NULL; | 469 | struct pci_dev *pci_dev = NULL; |
449 | extern void sn_init_cpei_timer(void); | 470 | extern void sn_init_cpei_timer(void); |
450 | #ifdef CONFIG_PROC_FS | 471 | #ifdef CONFIG_PROC_FS |
@@ -464,6 +485,7 @@ static int __init sn_pci_init(void) | |||
464 | 485 | ||
465 | pcibr_init_provider(); | 486 | pcibr_init_provider(); |
466 | tioca_init_provider(); | 487 | tioca_init_provider(); |
488 | tioce_init_provider(); | ||
467 | 489 | ||
468 | /* | 490 | /* |
469 | * This is needed to avoid bounce limit checks in the blk layer | 491 | * This is needed to avoid bounce limit checks in the blk layer |
@@ -479,8 +501,9 @@ static int __init sn_pci_init(void) | |||
479 | #endif | 501 | #endif |
480 | 502 | ||
481 | /* busses are not known yet ... */ | 503 | /* busses are not known yet ... */ |
482 | for (i = 0; i < PCI_BUSES_TO_SCAN; i++) | 504 | for (i = 0; i <= max_segment_number; i++) |
483 | sn_pci_controller_fixup(0, i, NULL); | 505 | for (j = 0; j <= max_pcibus_number; j++) |
506 | sn_pci_controller_fixup(i, j, NULL); | ||
484 | 507 | ||
485 | /* | 508 | /* |
486 | * Generic Linux PCI Layer has created the pci_bus and pci_dev | 509 | * Generic Linux PCI Layer has created the pci_bus and pci_dev |