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);
|
netif_device_attach(netdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void fm10k_io_reset_prepare(struct pci_dev *pdev)
|
||||||
* fm10k_io_reset_notify - called when PCI function is reset
|
{
|
||||||
* @pdev: Pointer to PCI device
|
/* warn incase we have any active VF devices */
|
||||||
*
|
if (pci_num_vf(pdev))
|
||||||
* This callback is called when the PCI function is reset such as from
|
dev_warn(&pdev->dev,
|
||||||
* /sys/class/net/<enpX>/device/reset or similar. When prepare is true, it
|
"PCIe FLR may cause issues for any active VF devices\n");
|
||||||
* means we should prepare for a function reset. If prepare is false, it means
|
fm10k_prepare_suspend(pci_get_drvdata(pdev));
|
||||||
* the function reset just occurred.
|
}
|
||||||
*/
|
|
||||||
static void fm10k_io_reset_notify(struct pci_dev *pdev, bool prepare)
|
static void fm10k_io_reset_done(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct fm10k_intfc *interface = pci_get_drvdata(pdev);
|
struct fm10k_intfc *interface = pci_get_drvdata(pdev);
|
||||||
int err = 0;
|
int err = fm10k_handle_resume(interface);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_warn(&pdev->dev,
|
dev_warn(&pdev->dev,
|
||||||
@ -2384,7 +2373,8 @@ static const struct pci_error_handlers fm10k_err_handler = {
|
|||||||
.error_detected = fm10k_io_error_detected,
|
.error_detected = fm10k_io_error_detected,
|
||||||
.slot_reset = fm10k_io_slot_reset,
|
.slot_reset = fm10k_io_slot_reset,
|
||||||
.resume = fm10k_io_resume,
|
.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 = {
|
static struct pci_driver fm10k_driver = {
|
||||||
|
@ -346,7 +346,37 @@ static const struct pci_device_id mwifiex_ids[] = {
|
|||||||
|
|
||||||
MODULE_DEVICE_TABLE(pci, 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 pcie_service_card *card = pci_get_drvdata(pdev);
|
||||||
struct mwifiex_adapter *adapter = card->adapter;
|
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,
|
mwifiex_dbg(adapter, INFO,
|
||||||
"%s: vendor=0x%4.04x device=0x%4.04x rev=%d %s\n",
|
"%s: vendor=0x%4.04x device=0x%4.04x rev=%d Post-FLR\n",
|
||||||
__func__, pdev->vendor, pdev->device,
|
__func__, pdev->vendor, pdev->device, pdev->revision);
|
||||||
pdev->revision,
|
|
||||||
prepare ? "Pre-FLR" : "Post-FLR");
|
|
||||||
|
|
||||||
if (prepare) {
|
adapter->surprise_removed = false;
|
||||||
/* Kernel would be performing FLR after this notification.
|
ret = mwifiex_reinit_sw(adapter);
|
||||||
* Cleanup all software without cleaning anything related to
|
if (ret)
|
||||||
* PCIe and HW.
|
dev_err(&pdev->dev, "reinit failed: %d\n", ret);
|
||||||
*/
|
else
|
||||||
mwifiex_shutdown_sw(adapter);
|
mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__);
|
||||||
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__);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pci_error_handlers mwifiex_pcie_err_handler[] = {
|
static const struct pci_error_handlers mwifiex_pcie_err_handler = {
|
||||||
{ .reset_notify = mwifiex_pcie_reset_notify, },
|
.reset_prepare = mwifiex_pcie_reset_prepare,
|
||||||
|
.reset_done = mwifiex_pcie_reset_done,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
@ -410,7 +423,7 @@ static struct pci_driver __refdata mwifiex_pcie = {
|
|||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
.shutdown = mwifiex_pcie_shutdown,
|
.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;
|
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)
|
static void nvme_reset_done(struct pci_dev *pdev)
|
||||||
nvme_dev_disable(dev, false);
|
{
|
||||||
else
|
nvme_reset(pci_get_drvdata(pdev));
|
||||||
nvme_reset(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nvme_shutdown(struct pci_dev *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,
|
.error_detected = nvme_error_detected,
|
||||||
.slot_reset = nvme_slot_reset,
|
.slot_reset = nvme_slot_reset,
|
||||||
.resume = nvme_error_resume,
|
.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[] = {
|
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_cfg_access_unlock(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void pci_dev_save_and_disable(struct pci_dev *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)
|
|
||||||
{
|
{
|
||||||
const struct pci_error_handlers *err_handler =
|
const struct pci_error_handlers *err_handler =
|
||||||
dev->driver ? dev->driver->err_handler : NULL;
|
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
|
* races with ->remove() by the device lock, which must be held by
|
||||||
* the caller.
|
* the caller.
|
||||||
*/
|
*/
|
||||||
if (err_handler && err_handler->reset_notify)
|
if (err_handler && err_handler->reset_prepare)
|
||||||
err_handler->reset_notify(dev, prepare);
|
err_handler->reset_prepare(dev);
|
||||||
}
|
|
||||||
|
|
||||||
static void pci_dev_save_and_disable(struct pci_dev *dev)
|
|
||||||
{
|
|
||||||
pci_reset_notify(dev, true);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wake-up device prior to save. PM registers default to D0 after
|
* 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)
|
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_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)
|
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_ers_result_t (*slot_reset)(struct pci_dev *dev);
|
||||||
|
|
||||||
/* PCI function reset prepare or completed */
|
/* 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 */
|
/* Device driver may resume normal operations */
|
||||||
void (*resume)(struct pci_dev *dev);
|
void (*resume)(struct pci_dev *dev);
|
||||||
|
Loading…
Reference in New Issue
Block a user