mirror of
https://github.com/torvalds/linux.git
synced 2024-11-18 01:51:53 +00:00
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: Christoph Hellwig <hch@lst.de> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
b014e96d1a
commit
775755ed3c
@ -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)
|
||||
{
|
||||
/* 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));
|
||||
}
|
||||
|
||||
static void fm10k_io_reset_done(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);
|
||||
}
|
||||
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 = {
|
||||
|
@ -346,7 +346,37 @@ 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;
|
||||
|
||||
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 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__);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
@ -359,37 +389,20 @@ 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 Post-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
|
||||
*/
|
||||
adapter->surprise_removed = false;
|
||||
ret = mwifiex_reinit_sw(adapter);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "reinit failed: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
|
||||
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_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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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[] = {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user