We should not release resource in pci_destroy that is too early
as there could be still other use hold reference.

release them or remove it from bus devices list at last
in pci_release_dev instead.

Signed-off-by: Yinghai Lu <ying...@kernel.org>

---
 drivers/pci/probe.c  |   20 ++++++++++++++++++++
 drivers/pci/remove.c |   19 -------------------
 2 files changed, 20 insertions(+), 19 deletions(-)

Index: linux-2.6/drivers/pci/probe.c
===================================================================
--- linux-2.6.orig/drivers/pci/probe.c
+++ linux-2.6/drivers/pci/probe.c
@@ -1118,6 +1118,20 @@ static void pci_release_capabilities(str
        pci_free_cap_save_buffers(dev);
 }
 
+static void pci_free_resources(struct pci_dev *dev)
+{
+       int i;
+
+       msi_remove_pci_irq_vectors(dev);
+
+       pci_cleanup_rom(dev);
+       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+               struct resource *res = dev->resource + i;
+               if (res->parent)
+                       release_resource(res);
+       }
+}
+
 /**
  * pci_release_dev - free a pci device structure when all users of it are 
finished.
  * @dev: device that's been disconnected
@@ -1130,6 +1144,12 @@ static void pci_release_dev(struct devic
        struct pci_dev *pci_dev;
 
        pci_dev = to_pci_dev(dev);
+
+       down_write(&pci_bus_sem);
+       list_del(&pci_dev->bus_list);
+       up_write(&pci_bus_sem);
+       pci_free_resources(pci_dev);
+
        pci_release_capabilities(pci_dev);
        pci_release_of_node(pci_dev);
        kfree(pci_dev);
Index: linux-2.6/drivers/pci/remove.c
===================================================================
--- linux-2.6.orig/drivers/pci/remove.c
+++ linux-2.6/drivers/pci/remove.c
@@ -3,20 +3,6 @@
 #include <linux/pci-aspm.h>
 #include "pci.h"
 
-static void pci_free_resources(struct pci_dev *dev)
-{
-       int i;
-
-       msi_remove_pci_irq_vectors(dev);
-
-       pci_cleanup_rom(dev);
-       for (i = 0; i < PCI_NUM_RESOURCES; i++) {
-               struct resource *res = dev->resource + i;
-               if (res->parent)
-                       release_resource(res);
-       }
-}
-
 static void pci_stop_dev(struct pci_dev *dev)
 {
        pci_pme_active(dev, false);
@@ -34,11 +20,6 @@ static void pci_stop_dev(struct pci_dev
 
 static void pci_destroy_dev(struct pci_dev *dev)
 {
-       down_write(&pci_bus_sem);
-       list_del(&dev->bus_list);
-       up_write(&pci_bus_sem);
-
-       pci_free_resources(dev);
        put_device(&dev->dev);
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to