aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKristen Accardi <kristen.c.accardi@intel.com>2006-02-23 20:55:58 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-23 17:35:15 -0500
commit15a1ae74879925d0d3f71ebc3f56d0a2c5db393a (patch)
tree6629b5eec7c8fae0c4fcf0901c475c32e598ec58 /drivers
parentb89b7ea05a8f71426bd36ed12e6cd73179d0f720 (diff)
[PATCH] acpiphp: add new bus to acpi
If we add a new bridge with subordinate busses, we should call make sure that acpi is notified so that the PRT (if present) can be read and drivers who have registered on this bus will be notified when it is started. Also make sure to use the max reserved bus number for the starting the bus scan. Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c111
1 files changed, 109 insertions, 2 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 4e25d9c7cc39..fe0a6b7662f7 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -751,6 +751,106 @@ static int power_off_slot(struct acpiphp_slot *slot)
751} 751}
752 752
753 753
754
755/**
756 * acpiphp_max_busnr - return the highest reserved bus number under
757 * the given bus.
758 * @bus: bus to start search with
759 *
760 */
761static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
762{
763 struct list_head *tmp;
764 unsigned char max, n;
765
766 /*
767 * pci_bus_max_busnr will return the highest
768 * reserved busnr for all these children.
769 * that is equivalent to the bus->subordinate
770 * value. We don't want to use the parent's
771 * bus->subordinate value because it could have
772 * padding in it.
773 */
774 max = bus->secondary;
775
776 list_for_each(tmp, &bus->children) {
777 n = pci_bus_max_busnr(pci_bus_b(tmp));
778 if (n > max)
779 max = n;
780 }
781 return max;
782}
783
784
785
786/**
787 * get_func - get a pointer to acpiphp_func given a slot, device
788 * @slot: slot to search
789 * @dev: pci_dev struct to match.
790 *
791 * This function will increase the reference count of pci_dev,
792 * so callers should call pci_dev_put when complete.
793 *
794 */
795static struct acpiphp_func *
796get_func(struct acpiphp_slot *slot, struct pci_dev *dev)
797{
798 struct acpiphp_func *func = NULL;
799 struct pci_bus *bus = slot->bridge->pci_bus;
800 struct pci_dev *pdev;
801
802 list_for_each_entry(func, &slot->funcs, sibling) {
803 pdev = pci_get_slot(bus, PCI_DEVFN(slot->device,
804 func->function));
805 if (pdev) {
806 if (pdev == dev)
807 break;
808 pci_dev_put(pdev);
809 }
810 }
811 return func;
812}
813
814
815/**
816 * acpiphp_bus_add - add a new bus to acpi subsystem
817 * @func: acpiphp_func of the bridge
818 *
819 */
820static int acpiphp_bus_add(struct acpiphp_func *func)
821{
822 acpi_handle phandle;
823 struct acpi_device *device, *pdevice;
824 int ret_val;
825
826 acpi_get_parent(func->handle, &phandle);
827 if (acpi_bus_get_device(phandle, &pdevice)) {
828 dbg("no parent device, assuming NULL\n");
829 pdevice = NULL;
830 }
831 if (acpi_bus_get_device(func->handle, &device)) {
832 ret_val = acpi_bus_add(&device, pdevice, func->handle,
833 ACPI_BUS_TYPE_DEVICE);
834 if (ret_val) {
835 dbg("error adding bus, %x\n",
836 -ret_val);
837 goto acpiphp_bus_add_out;
838 }
839 }
840 /*
841 * try to start anyway. We could have failed to add
842 * simply because this bus had previously been added
843 * on another add. Don't bother with the return value
844 * we just keep going.
845 */
846 ret_val = acpi_bus_start(device);
847
848acpiphp_bus_add_out:
849 return ret_val;
850}
851
852
853
754/** 854/**
755 * enable_device - enable, configure a slot 855 * enable_device - enable, configure a slot
756 * @slot: slot to be enabled 856 * @slot: slot to be enabled
@@ -788,7 +888,7 @@ static int enable_device(struct acpiphp_slot *slot)
788 goto err_exit; 888 goto err_exit;
789 } 889 }
790 890
791 max = bus->secondary; 891 max = acpiphp_max_busnr(bus);
792 for (pass = 0; pass < 2; pass++) { 892 for (pass = 0; pass < 2; pass++) {
793 list_for_each_entry(dev, &bus->devices, bus_list) { 893 list_for_each_entry(dev, &bus->devices, bus_list) {
794 if (PCI_SLOT(dev->devfn) != slot->device) 894 if (PCI_SLOT(dev->devfn) != slot->device)
@@ -796,8 +896,15 @@ static int enable_device(struct acpiphp_slot *slot)
796 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 896 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
797 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 897 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
798 max = pci_scan_bridge(bus, dev, max, pass); 898 max = pci_scan_bridge(bus, dev, max, pass);
799 if (pass && dev->subordinate) 899 if (pass && dev->subordinate) {
800 pci_bus_size_bridges(dev->subordinate); 900 pci_bus_size_bridges(dev->subordinate);
901 func = get_func(slot, dev);
902 if (func) {
903 acpiphp_bus_add(func);
904 /* side effect of get_func */
905 pci_dev_put(dev);
906 }
907 }
801 } 908 }
802 } 909 }
803 } 910 }