aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorMUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>2006-03-22 00:49:09 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-19 17:13:21 -0400
commit92c9be95549632da09088320f202fa5c05b21ddf (patch)
tree744691b15a41c90f9eb6747aff01396c55222834 /drivers/pci
parente55dea58c5609aece6156a6cd2306b820a7794ef (diff)
[PATCH] acpiphp: configure _PRT - V3
Current acpiphp does not free acpi_device structs when the PCI devices are removed. When the PCI device is added, acpi_bus_add() fails because acpi_device struct has already exists. So, _PRT method does not evaluate. This patch fixes this issue. Signed-off-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c71
1 files changed, 33 insertions, 38 deletions
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index 053ee843863c..fadd264b64c3 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -797,36 +797,6 @@ static unsigned char acpiphp_max_busnr(struct pci_bus *bus)
797} 797}
798 798
799 799
800
801/**
802 * get_func - get a pointer to acpiphp_func given a slot, device
803 * @slot: slot to search
804 * @dev: pci_dev struct to match.
805 *
806 * This function will increase the reference count of pci_dev,
807 * so callers should call pci_dev_put when complete.
808 *
809 */
810static struct acpiphp_func *
811get_func(struct acpiphp_slot *slot, struct pci_dev *dev)
812{
813 struct acpiphp_func *func = NULL;
814 struct pci_bus *bus = slot->bridge->pci_bus;
815 struct pci_dev *pdev;
816
817 list_for_each_entry(func, &slot->funcs, sibling) {
818 pdev = pci_get_slot(bus, PCI_DEVFN(slot->device,
819 func->function));
820 if (pdev) {
821 if (pdev == dev)
822 break;
823 pci_dev_put(pdev);
824 }
825 }
826 return func;
827}
828
829
830/** 800/**
831 * acpiphp_bus_add - add a new bus to acpi subsystem 801 * acpiphp_bus_add - add a new bus to acpi subsystem
832 * @func: acpiphp_func of the bridge 802 * @func: acpiphp_func of the bridge
@@ -872,6 +842,28 @@ acpiphp_bus_add_out:
872} 842}
873 843
874 844
845/**
846 * acpiphp_bus_trim - trim a bus from acpi subsystem
847 * @handle: handle to acpi namespace
848 *
849 */
850int acpiphp_bus_trim(acpi_handle handle)
851{
852 struct acpi_device *device;
853 int retval;
854
855 retval = acpi_bus_get_device(handle, &device);
856 if (retval) {
857 dbg("acpi_device not found\n");
858 return retval;
859 }
860
861 retval = acpi_bus_trim(device, 1);
862 if (retval)
863 err("cannot remove from acpi list\n");
864
865 return retval;
866}
875 867
876/** 868/**
877 * enable_device - enable, configure a slot 869 * enable_device - enable, configure a slot
@@ -918,19 +910,17 @@ static int enable_device(struct acpiphp_slot *slot)
918 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 910 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
919 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) { 911 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
920 max = pci_scan_bridge(bus, dev, max, pass); 912 max = pci_scan_bridge(bus, dev, max, pass);
921 if (pass && dev->subordinate) { 913 if (pass && dev->subordinate)
922 pci_bus_size_bridges(dev->subordinate); 914 pci_bus_size_bridges(dev->subordinate);
923 func = get_func(slot, dev);
924 if (func) {
925 acpiphp_bus_add(func);
926 /* side effect of get_func */
927 pci_dev_put(dev);
928 }
929 }
930 } 915 }
931 } 916 }
932 } 917 }
933 918
919 list_for_each (l, &slot->funcs) {
920 func = list_entry(l, struct acpiphp_func, sibling);
921 acpiphp_bus_add(func);
922 }
923
934 pci_bus_assign_resources(bus); 924 pci_bus_assign_resources(bus);
935 acpiphp_sanitize_bus(bus); 925 acpiphp_sanitize_bus(bus);
936 pci_enable_bridges(bus); 926 pci_enable_bridges(bus);
@@ -967,6 +957,11 @@ static int disable_device(struct acpiphp_slot *slot)
967 957
968 list_for_each (l, &slot->funcs) { 958 list_for_each (l, &slot->funcs) {
969 func = list_entry(l, struct acpiphp_func, sibling); 959 func = list_entry(l, struct acpiphp_func, sibling);
960
961 acpiphp_bus_trim(func->handle);
962 /* try to remove anyway.
963 * acpiphp_bus_add might have been failed */
964
970 if (!func->pci_dev) 965 if (!func->pci_dev)
971 continue; 966 continue;
972 967