Introduce a helper function pci_stop_and_remove_device(), which removes a PCI device in a safe way by locking parent and all affected descendant PCI buses. Signed-off-by: Jiang Liu <jiang.liu@xxxxxxxxxx> Cc: Yinghai Lu <yinghai@xxxxxxxxxx> Cc: linux-pci@xxxxxxxxxxxxxxx Cc: linux-kernel@xxxxxxxxxxxxxxx --- drivers/pci/remove.c | 19 +++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 20 insertions(+) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 2f01f72..8e9b272 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -1,6 +1,7 @@ #include <linux/pci.h> #include <linux/module.h> #include <linux/pci-aspm.h> +#include <linux/delay.h> #include "pci.h" static void pci_stop_bus_device(struct pci_dev *dev); @@ -148,6 +149,24 @@ void pci_stop_and_remove_bus_device(struct pci_dev *dev) } EXPORT_SYMBOL(pci_stop_and_remove_bus_device); +void pci_stop_and_remove_device(struct pci_dev *pdev) +{ + int ret; + struct pci_bus *bus = pdev->bus; + + do { + ret = pci_bus_lock_timeout(bus, PCI_BUS_STATE_STOPPING - 1, + true, HZ / 10); + if (ret == 0) { + pci_stop_and_remove_bus_device(pdev); + pci_bus_unlock(bus, true); + break; + } + } while (pci_bus_get_state(bus) <= PCI_BUS_STATE_STARTED && + pci_dev_get_state(pdev) <= PCI_DEV_STATE_STARTED); +} +EXPORT_SYMBOL(pci_stop_and_remove_device); + void pci_stop_root_bus(struct pci_bus *bus) { BUG_ON(!pci_bus_is_locked(bus)); diff --git a/include/linux/pci.h b/include/linux/pci.h index d3f61f8..45d4aea 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -817,6 +817,7 @@ struct pci_dev *pci_dev_get(struct pci_dev *dev); void pci_dev_put(struct pci_dev *dev); void pci_remove_bus(struct pci_bus *b); void pci_stop_and_remove_bus_device(struct pci_dev *dev); +void pci_stop_and_remove_device(struct pci_dev *dev); void pci_stop_root_bus(struct pci_bus *bus); void pci_remove_root_bus(struct pci_bus *bus); void pci_setup_cardbus(struct pci_bus *bus); -- 1.8.1.2 -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html