acpiphp: disable bridges
authorSatoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Tue, 12 Sep 2006 17:19:00 +0000 (10:19 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 27 Sep 2006 00:43:54 +0000 (17:43 -0700)
Currently acpiphp calls pci_enable_device() against all
hot-added bridges, but acpiphp does not call pci_disable_device()
against them in hot-remove. So ioapic hot-remove would fail.
This patch fixes this issue.

Signed-off-by: Kenji Kaneshige <kaneshige.kenji@jp.fujitsu.com>
Signed-off-by: MUNEDA Takahiro <muneda.takahiro@jp.fujitsu.com>
Signed-off-by: Satoru Takeuchi <takeuchi_satoru@jp.fujitsu.com>
Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/pci/hotplug/acpiphp_glue.c

index d36732c..712f02f 100644 (file)
@@ -1105,6 +1105,16 @@ static int enable_device(struct acpiphp_slot *slot)
        return retval;
 }
 
+static void disable_bridges(struct pci_bus *bus)
+{
+       struct pci_dev *dev;
+       list_for_each_entry(dev, &bus->devices, bus_list) {
+               if (dev->subordinate) {
+                       disable_bridges(dev->subordinate);
+                       pci_disable_device(dev);
+               }
+       }
+}
 
 /**
  * disable_device - disable a slot
@@ -1129,8 +1139,13 @@ static int disable_device(struct acpiphp_slot *slot)
                        func->bridge = NULL;
                }
 
-               if (func->pci_dev)
+               if (func->pci_dev) {
                        pci_stop_bus_device(func->pci_dev);
+                       if (func->pci_dev->subordinate) {
+                               disable_bridges(func->pci_dev->subordinate);
+                               pci_disable_device(func->pci_dev);
+                       }
+               }
 
                acpiphp_bus_trim(func->handle);
                /* try to remove anyway.