Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 775755ed authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Bjorn Helgaas
Browse files

PCI: Split ->reset_notify() method into ->reset_prepare() and ->reset_done()

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: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent b014e96d
Loading
Loading
Loading
Loading
+13 −23
Original line number Diff line number Diff line
@@ -2348,31 +2348,20 @@ 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");

		fm10k_prepare_suspend(interface);
	} else {
		err = fm10k_handle_resume(interface);
	fm10k_prepare_suspend(pci_get_drvdata(pdev));
}

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,
			 "fm10k_io_reset_notify failed: %d\n", err);
@@ -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 = {
+44 −31
Original line number Diff line number Diff line
@@ -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");
		    "%s: vendor=0x%4.04x device=0x%4.04x rev=%d Pre-FLR\n",
		    __func__, pdev->vendor, pdev->device, pdev->revision);

	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
	mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}

/*
 * 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) {
	if (ret)
		dev_err(&pdev->dev, "reinit failed: %d\n", ret);
			return;
		}
	}
	else
		mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
}

static const struct pci_error_handlers mwifiex_pcie_err_handler[] = {
		{ .reset_notify = mwifiex_pcie_reset_notify, },
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,
};

/*
+8 −7
Original line number Diff line number Diff line
@@ -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[] = {
+15 −19
Original line number Diff line number Diff line
@@ -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)
+2 −1
Original line number Diff line number Diff line
@@ -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);