diff options
Diffstat (limited to 'drivers/pci/hotplug/sgi_hotplug.c')
-rw-r--r-- | drivers/pci/hotplug/sgi_hotplug.c | 73 |
1 files changed, 32 insertions, 41 deletions
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index f64ca92253da..180e760c1653 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -334,7 +334,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
334 | struct slot *slot = bss_hotplug_slot->private; | 334 | struct slot *slot = bss_hotplug_slot->private; |
335 | struct pci_bus *new_bus = NULL; | 335 | struct pci_bus *new_bus = NULL; |
336 | struct pci_dev *dev; | 336 | struct pci_dev *dev; |
337 | int func, num_funcs; | 337 | int num_funcs; |
338 | int new_ppb = 0; | 338 | int new_ppb = 0; |
339 | int rc; | 339 | int rc; |
340 | char *ssdt = NULL; | 340 | char *ssdt = NULL; |
@@ -381,29 +381,26 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
381 | * to the Linux PCI interface and tell the drivers | 381 | * to the Linux PCI interface and tell the drivers |
382 | * about them. | 382 | * about them. |
383 | */ | 383 | */ |
384 | for (func = 0; func < num_funcs; func++) { | 384 | list_for_each_entry(dev, &slot->pci_bus->devices, bus_list) { |
385 | dev = pci_get_slot(slot->pci_bus, | 385 | if (PCI_SLOT(dev->devfn) != slot->device_num + 1) |
386 | PCI_DEVFN(slot->device_num + 1, | 386 | continue; |
387 | PCI_FUNC(func))); | 387 | |
388 | if (dev) { | 388 | /* Need to do slot fixup on PPB before fixup of children |
389 | /* Need to do slot fixup on PPB before fixup of children | 389 | * (PPB's pcidev_info needs to be in pcidev_info list |
390 | * (PPB's pcidev_info needs to be in pcidev_info list | 390 | * before child's SN_PCIDEV_INFO() call to setup |
391 | * before child's SN_PCIDEV_INFO() call to setup | 391 | * pdi_host_pcidev_info). |
392 | * pdi_host_pcidev_info). | 392 | */ |
393 | */ | 393 | pcibios_fixup_device_resources(dev); |
394 | pcibios_fixup_device_resources(dev); | 394 | if (SN_ACPI_BASE_SUPPORT()) |
395 | if (SN_ACPI_BASE_SUPPORT()) | 395 | sn_acpi_slot_fixup(dev); |
396 | sn_acpi_slot_fixup(dev); | 396 | else |
397 | else | 397 | sn_io_slot_fixup(dev); |
398 | sn_io_slot_fixup(dev); | 398 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
399 | if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 399 | pci_hp_add_bridge(dev); |
400 | pci_hp_add_bridge(dev); | 400 | if (dev->subordinate) { |
401 | if (dev->subordinate) { | 401 | new_bus = dev->subordinate; |
402 | new_bus = dev->subordinate; | 402 | new_ppb = 1; |
403 | new_ppb = 1; | ||
404 | } | ||
405 | } | 403 | } |
406 | pci_dev_put(dev); | ||
407 | } | 404 | } |
408 | } | 405 | } |
409 | 406 | ||
@@ -412,7 +409,6 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
412 | if (SN_ACPI_BASE_SUPPORT() && ssdt) { | 409 | if (SN_ACPI_BASE_SUPPORT() && ssdt) { |
413 | unsigned long long adr; | 410 | unsigned long long adr; |
414 | struct acpi_device *pdevice; | 411 | struct acpi_device *pdevice; |
415 | struct acpi_device *device; | ||
416 | acpi_handle phandle; | 412 | acpi_handle phandle; |
417 | acpi_handle chandle = NULL; | 413 | acpi_handle chandle = NULL; |
418 | acpi_handle rethandle; | 414 | acpi_handle rethandle; |
@@ -448,17 +444,14 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
448 | if (ACPI_SUCCESS(ret) && | 444 | if (ACPI_SUCCESS(ret) && |
449 | (adr>>16) == (slot->device_num + 1)) { | 445 | (adr>>16) == (slot->device_num + 1)) { |
450 | 446 | ||
451 | ret = acpi_bus_add(&device, pdevice, chandle, | 447 | ret = acpi_bus_scan(chandle); |
452 | ACPI_BUS_TYPE_DEVICE); | ||
453 | if (ACPI_FAILURE(ret)) { | 448 | if (ACPI_FAILURE(ret)) { |
454 | printk(KERN_ERR "%s: acpi_bus_add " | 449 | printk(KERN_ERR "%s: acpi_bus_scan " |
455 | "failed (0x%x) for slot %d " | 450 | "failed (0x%x) for slot %d " |
456 | "func %d\n", __func__, | 451 | "func %d\n", __func__, |
457 | ret, (int)(adr>>16), | 452 | ret, (int)(adr>>16), |
458 | (int)(adr&0xffff)); | 453 | (int)(adr&0xffff)); |
459 | /* try to continue on */ | 454 | /* try to continue on */ |
460 | } else { | ||
461 | acpi_bus_start(device); | ||
462 | } | 455 | } |
463 | } | 456 | } |
464 | } | 457 | } |
@@ -485,8 +478,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
485 | static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | 478 | static int disable_slot(struct hotplug_slot *bss_hotplug_slot) |
486 | { | 479 | { |
487 | struct slot *slot = bss_hotplug_slot->private; | 480 | struct slot *slot = bss_hotplug_slot->private; |
488 | struct pci_dev *dev; | 481 | struct pci_dev *dev, *temp; |
489 | int func; | ||
490 | int rc; | 482 | int rc; |
491 | acpi_owner_id ssdt_id = 0; | 483 | acpi_owner_id ssdt_id = 0; |
492 | 484 | ||
@@ -539,22 +531,21 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot) | |||
539 | ret = acpi_bus_get_device(chandle, | 531 | ret = acpi_bus_get_device(chandle, |
540 | &device); | 532 | &device); |
541 | if (ACPI_SUCCESS(ret)) | 533 | if (ACPI_SUCCESS(ret)) |
542 | acpi_bus_trim(device, 1); | 534 | acpi_bus_trim(device); |
543 | } | 535 | } |
544 | } | 536 | } |
545 | 537 | ||
546 | } | 538 | } |
547 | 539 | ||
548 | /* Free the SN resources assigned to the Linux device.*/ | 540 | /* Free the SN resources assigned to the Linux device.*/ |
549 | for (func = 0; func < 8; func++) { | 541 | list_for_each_entry_safe(dev, temp, &slot->pci_bus->devices, bus_list) { |
550 | dev = pci_get_slot(slot->pci_bus, | 542 | if (PCI_SLOT(dev->devfn) != slot->device_num + 1) |
551 | PCI_DEVFN(slot->device_num + 1, | 543 | continue; |
552 | PCI_FUNC(func))); | 544 | |
553 | if (dev) { | 545 | pci_dev_get(dev); |
554 | sn_bus_free_data(dev); | 546 | sn_bus_free_data(dev); |
555 | pci_stop_and_remove_bus_device(dev); | 547 | pci_stop_and_remove_bus_device(dev); |
556 | pci_dev_put(dev); | 548 | pci_dev_put(dev); |
557 | } | ||
558 | } | 549 | } |
559 | 550 | ||
560 | /* Remove the SSDT for the slot from the ACPI namespace */ | 551 | /* Remove the SSDT for the slot from the ACPI namespace */ |