diff options
Diffstat (limited to 'arch/ia64/sn/kernel/io_init.c')
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 33 |
1 files changed, 27 insertions, 6 deletions
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 |