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 | |
| 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>
| -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); |
