diff options
author | Prarit Bhargava <prarit@sgi.com> | 2005-08-02 13:08:00 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2005-08-16 18:24:48 -0400 |
commit | c1ffb910f7a4e1e79d462bb359067d97ad1a8a25 (patch) | |
tree | dcf395e9526f0c3bf56fb4fe4bed1586126fda3f /arch/ia64/sn/kernel/io_init.c | |
parent | 12aaa0855b39b5464db953fedf399fa91ee365ed (diff) |
[IA64]: SN fix bus->sysdata pointer and memory cleanups
The main issue is that bus_fixup calls may potentially call
functions that require a valid bus->sysdata pointer. Since
this is the case, we must set the bus->sysdata pointer before
calling the bus_fixup functions. The remaining changes are
simple fixes to make sure memory is cleaned up in the function.
Signed-off-by: Prarit Bhargava <prarit@sgi.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch/ia64/sn/kernel/io_init.c')
-rw-r--r-- | arch/ia64/sn/kernel/io_init.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index a6649baf629a..7566a97b0ce1 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -322,7 +322,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
322 | struct pci_controller *controller; | 322 | struct pci_controller *controller; |
323 | struct pcibus_bussoft *prom_bussoft_ptr; | 323 | struct pcibus_bussoft *prom_bussoft_ptr; |
324 | struct hubdev_info *hubdev_info; | 324 | struct hubdev_info *hubdev_info; |
325 | void *provider_soft; | 325 | void *provider_soft = NULL; |
326 | struct sn_pcibus_provider *provider; | 326 | struct sn_pcibus_provider *provider; |
327 | 327 | ||
328 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, | 328 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, |
@@ -338,7 +338,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
338 | if (bus == NULL) { | 338 | if (bus == NULL) { |
339 | bus = pci_scan_bus(busnum, &pci_root_ops, controller); | 339 | bus = pci_scan_bus(busnum, &pci_root_ops, controller); |
340 | if (bus == NULL) | 340 | if (bus == NULL) |
341 | return; /* error, or bus already scanned */ | 341 | goto error_return; /* error, or bus already scanned */ |
342 | bus->sysdata = NULL; | 342 | bus->sysdata = NULL; |
343 | } | 343 | } |
344 | 344 | ||
@@ -351,28 +351,30 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
351 | */ | 351 | */ |
352 | 352 | ||
353 | if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) | 353 | if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) |
354 | return; /* unsupported asic type */ | 354 | goto error_return; /* unsupported asic type */ |
355 | 355 | ||
356 | if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) | 356 | if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) |
357 | goto error_return; /* no further fixup necessary */ | 357 | goto error_return; /* no further fixup necessary */ |
358 | 358 | ||
359 | provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; | 359 | provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; |
360 | if (provider == NULL) | 360 | if (provider == NULL) |
361 | return; /* no provider registerd for this asic */ | 361 | goto error_return; /* no provider registerd for this asic */ |
362 | 362 | ||
363 | provider_soft = NULL; | 363 | bus->sysdata = controller; |
364 | if (provider->bus_fixup) | 364 | if (provider->bus_fixup) |
365 | provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); | 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 | /* fixup failed or not applicable */ |
369 | bus->sysdata = NULL; | ||
370 | goto error_return; | ||
371 | } | ||
369 | 372 | ||
370 | /* | 373 | /* |
371 | * Generic bus fixup goes here. Don't reference prom_bussoft_ptr | 374 | * Generic bus fixup goes here. Don't reference prom_bussoft_ptr |
372 | * after this point. | 375 | * after this point. |
373 | */ | 376 | */ |
374 | 377 | ||
375 | bus->sysdata = controller; | ||
376 | PCI_CONTROLLER(bus)->platform_data = provider_soft; | 378 | PCI_CONTROLLER(bus)->platform_data = provider_soft; |
377 | nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); | 379 | nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); |
378 | cnode = nasid_to_cnodeid(nasid); | 380 | cnode = nasid_to_cnodeid(nasid); |