PCI: Split ->reset_notify() method into ->reset_prepare() and ->reset_done()
authorChristoph Hellwig <hch@lst.de>
Thu, 1 Jun 2017 11:10:38 +0000 (13:10 +0200)
committerBjorn Helgaas <bhelgaas@google.com>
Mon, 3 Jul 2017 12:58:30 +0000 (07:58 -0500)
The pci_error_handlers->reset_notify() method had a flag to indicate
whether to prepare for or clean up after a reset.  The prepare and done
cases have no shared functionality whatsoever, so split them into separate
methods.

[bhelgaas: changelog, update locking comments]
Link: http://lkml.kernel.org/r/20170601111039.8913-3-hch@lst.de
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/net/ethernet/intel/fm10k/fm10k_pci.c
drivers/net/wireless/marvell/mwifiex/pcie.c
drivers/nvme/host/pci.c
drivers/pci/pci.c
include/linux/pci.h

index 3e26d27ad213362bcc473262435740ccf8d2c697..63784576ae8b392215b6b6d7dcee13036901e548 100644 (file)
@@ -2348,30 +2348,19 @@ static void fm10k_io_resume(struct pci_dev *pdev)
                netif_device_attach(netdev);
 }
 
-/**
- * fm10k_io_reset_notify - called when PCI function is reset
- * @pdev: Pointer to PCI device
- *
- * This callback is called when the PCI function is reset such as from
- * /sys/class/net/<enpX>/device/reset or similar. When prepare is true, it
- * means we should prepare for a function reset. If prepare is false, it means
- * the function reset just occurred.
- */
-static void fm10k_io_reset_notify(struct pci_dev *pdev, bool prepare)
+static void fm10k_io_reset_prepare(struct pci_dev *pdev)
 {
-       struct fm10k_intfc *interface = pci_get_drvdata(pdev);
-       int err = 0;
-
-       if (prepare) {
-               /* warn incase we have any active VF devices */
-               if (pci_num_vf(pdev))
-                       dev_warn(&pdev->dev,
-                                "PCIe FLR may cause issues for any active VF devices\n");
+       /* warn incase we have any active VF devices */
+       if (pci_num_vf(pdev))
+               dev_warn(&pdev->dev,
+                        "PCIe FLR may cause issues for any active VF devices\n");
+       fm10k_prepare_suspend(pci_get_drvdata(pdev));
+}
 
-               fm10k_prepare_suspend(interface);
-       } else {
-               err = fm10k_handle_resume(interface);
-       }
+static void fm10k_io_reset_done(struct pci_dev *pdev)
+{
+       struct fm10k_intfc *interface = pci_get_drvdata(pdev);
+       int err = fm10k_handle_resume(interface);
 
        if (err) {
                dev_warn(&pdev->dev,
@@ -2384,7 +2373,8 @@ static const struct pci_error_handlers fm10k_err_handler = {
        .error_detected = fm10k_io_error_detected,
        .slot_reset = fm10k_io_slot_reset,
        .resume = fm10k_io_resume,
-       .reset_notify = fm10k_io_reset_notify,
+       .reset_prepare = fm10k_io_reset_prepare,
+       .reset_done = fm10k_io_reset_done,
 };
 
 static struct pci_driver fm10k_driver = {
index ac62bce50e964b900135cdc600dcdb9032928a3f..279adf124fc9613f96346ebfde55d0e9ea8d56ff 100644 (file)
@@ -346,11 +346,13 @@ static const struct pci_device_id mwifiex_ids[] = {
 
 MODULE_DEVICE_TABLE(pci, mwifiex_ids);
 
-static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
+/*
+ * Cleanup all software without cleaning anything related to PCIe and HW.
+ */
+static void mwifiex_pcie_reset_prepare(struct pci_dev *pdev)
 {
        struct pcie_service_card *card = pci_get_drvdata(pdev);
        struct mwifiex_adapter *adapter = card->adapter;
-       int ret;
 
        if (!adapter) {
                dev_err(&pdev->dev, "%s: adapter structure is not valid\n",
@@ -359,37 +361,48 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare)
        }
 
        mwifiex_dbg(adapter, INFO,
-                   "%s: vendor=0x%4.04x device=0x%4.04x rev=%d %s\n",
-                   __func__, pdev->vendor, pdev->device,
-                   pdev->revision,
-                   prepare ? "Pre-FLR" : "Post-FLR");
-
-       if (prepare) {
-               /* Kernel would be performing FLR after this notification.
-                * Cleanup all software without cleaning anything related to
-                * PCIe and HW.
-                */
-               mwifiex_shutdown_sw(adapter);
-               adapter->surprise_removed = true;
-               clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
-               clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
-       } else {
-               /* Kernel stores and restores PCIe function context before and
-                * after performing FLR respectively. Reconfigure the software
-                * and firmware including firmware redownload
-                */
-               adapter->surprise_removed = false;
-               ret = mwifiex_reinit_sw(adapter);
-               if (ret) {
-                       dev_err(&pdev->dev, "reinit failed: %d\n", ret);
-                       return;
-               }
-       }
+                   "%s: vendor=0x%4.04x device=0x%4.04x rev=%d Pre-FLR\n",
+                   __func__, pdev->vendor, pdev->device, pdev->revision);
+
+       mwifiex_shutdown_sw(adapter);
+       adapter->surprise_removed = true;
+       clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);
+       clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);
        mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
 }
 
-static const struct pci_error_handlers mwifiex_pcie_err_handler[] = {
-               { .reset_notify = mwifiex_pcie_reset_notify, },
+/*
+ * Kernel stores and restores PCIe function context before and after performing
+ * FLR respectively. Reconfigure the software and firmware including firmware
+ * redownload.
+ */
+static void mwifiex_pcie_reset_done(struct pci_dev *pdev)
+{
+       struct pcie_service_card *card = pci_get_drvdata(pdev);
+       struct mwifiex_adapter *adapter = card->adapter;
+       int ret;
+
+       if (!adapter) {
+               dev_err(&pdev->dev, "%s: adapter structure is not valid\n",
+                       __func__);
+               return;
+       }
+
+       mwifiex_dbg(adapter, INFO,
+                   "%s: vendor=0x%4.04x device=0x%4.04x rev=%d Post-FLR\n",
+                   __func__, pdev->vendor, pdev->device, pdev->revision);
+
+       adapter->surprise_removed = false;
+       ret = mwifiex_reinit_sw(adapter);
+       if (ret)
+               dev_err(&pdev->dev, "reinit failed: %d\n", ret);
+       else
+               mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
+}
+
+static const struct pci_error_handlers mwifiex_pcie_err_handler = {
+       .reset_prepare          = mwifiex_pcie_reset_prepare,
+       .reset_done             = mwifiex_pcie_reset_done,
 };
 
 #ifdef CONFIG_PM_SLEEP
@@ -410,7 +423,7 @@ static struct pci_driver __refdata mwifiex_pcie = {
        },
 #endif
        .shutdown = mwifiex_pcie_shutdown,
-       .err_handler = mwifiex_pcie_err_handler,
+       .err_handler = &mwifiex_pcie_err_handler,
 };
 
 /*
index fed803232edccbdf63139d89028c694efff52409..9a3d69b8df9894850d247cee477fff3bb138e56e 100644 (file)
@@ -2145,14 +2145,14 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        return result;
 }
 
-static void nvme_reset_notify(struct pci_dev *pdev, bool prepare)
+static void nvme_reset_prepare(struct pci_dev *pdev)
 {
-       struct nvme_dev *dev = pci_get_drvdata(pdev);
+       nvme_dev_disable(pci_get_drvdata(pdev), false);
+}
 
-       if (prepare)
-               nvme_dev_disable(dev, false);
-       else
-               nvme_reset(dev);
+static void nvme_reset_done(struct pci_dev *pdev)
+{
+       nvme_reset(pci_get_drvdata(pdev));
 }
 
 static void nvme_shutdown(struct pci_dev *pdev)
@@ -2275,7 +2275,8 @@ static const struct pci_error_handlers nvme_err_handler = {
        .error_detected = nvme_error_detected,
        .slot_reset     = nvme_slot_reset,
        .resume         = nvme_error_resume,
-       .reset_notify   = nvme_reset_notify,
+       .reset_prepare  = nvme_reset_prepare,
+       .reset_done     = nvme_reset_done,
 };
 
 static const struct pci_device_id nvme_id_table[] = {
index f4587f6f8739caea323ed01e3ce1caa8ca7a3536..56407eb1dc8825db85d0c8a5a3e1be0df983dd11 100644 (file)
@@ -4130,32 +4130,18 @@ static void pci_dev_unlock(struct pci_dev *dev)
        pci_cfg_access_unlock(dev);
 }
 
-/**
- * pci_reset_notify - notify device driver of reset
- * @dev: device to be notified of reset
- * @prepare: 'true' if device is about to be reset; 'false' if reset attempt
- *           completed
- *
- * Must be called prior to device access being disabled and after device
- * access is restored.
- */
-static void pci_reset_notify(struct pci_dev *dev, bool prepare)
+static void pci_dev_save_and_disable(struct pci_dev *dev)
 {
        const struct pci_error_handlers *err_handler =
                        dev->driver ? dev->driver->err_handler : NULL;
 
        /*
-        * dev->driver->err_handler->reset_notify() is protected against
+        * dev->driver->err_handler->reset_prepare() is protected against
         * races with ->remove() by the device lock, which must be held by
         * the caller.
         */
-       if (err_handler && err_handler->reset_notify)
-               err_handler->reset_notify(dev, prepare);
-}
-
-static void pci_dev_save_and_disable(struct pci_dev *dev)
-{
-       pci_reset_notify(dev, true);
+       if (err_handler && err_handler->reset_prepare)
+               err_handler->reset_prepare(dev);
 
        /*
         * Wake-up device prior to save.  PM registers default to D0 after
@@ -4177,8 +4163,18 @@ static void pci_dev_save_and_disable(struct pci_dev *dev)
 
 static void pci_dev_restore(struct pci_dev *dev)
 {
+       const struct pci_error_handlers *err_handler =
+                       dev->driver ? dev->driver->err_handler : NULL;
+
        pci_restore_state(dev);
-       pci_reset_notify(dev, false);
+
+       /*
+        * dev->driver->err_handler->reset_done() is protected against
+        * races with ->remove() by the device lock, which must be held by
+        * the caller.
+        */
+       if (err_handler && err_handler->reset_done)
+               err_handler->reset_done(dev);
 }
 
 static int pci_dev_reset(struct pci_dev *dev, int probe)
index c7cfdff2529c2dab45bcd52c8676ca0cbe597ca1..c5937ee7e7742abaac9b785a0ab433064ee2ccc6 100644 (file)
@@ -698,7 +698,8 @@ struct pci_error_handlers {
        pci_ers_result_t (*slot_reset)(struct pci_dev *dev);
 
        /* PCI function reset prepare or completed */
-       void (*reset_notify)(struct pci_dev *dev, bool prepare);
+       void (*reset_prepare)(struct pci_dev *dev);
+       void (*reset_done)(struct pci_dev *dev);
 
        /* Device driver may resume normal operations */
        void (*resume)(struct pci_dev *dev);