From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Jiang Liu To: Bjorn Helgaas , Yinghai Lu Cc: Jiang Liu , "Rafael J . Wysocki" , Greg Kroah-Hartman , Gu Zheng , Toshi Kani , Myron Stowe , Yijing Wang , Jiang Liu , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH v2, part3 04/11] PCI: introduce helper function pci_stop_and_remove_device() Date: Thu, 16 May 2013 23:50:52 +0800 Message-Id: <1368719459-24800-5-git-send-email-jiang.liu@huawei.com> In-Reply-To: <1368719459-24800-1-git-send-email-jiang.liu@huawei.com> References: <1368719459-24800-1-git-send-email-jiang.liu@huawei.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: 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 Cc: Yinghai Lu Cc: linux-pci@vger.kernel.org Cc: linux-kernel@vger.kernel.org --- 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 #include #include +#include #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