Commit 790d23e7 authored by Dirk van der Merwe's avatar Dirk van der Merwe Committed by David S. Miller

nfp: implement PCI driver shutdown callback

Device may be shutdown without the hardware being reinitialized, in
which case we want to ensure we cleanup properly.

This is especially important for kexec with traffic flowing.

The shutdown procedures resembles the remove procedures, so we can reuse
those common tasks.
Signed-off-by: default avatarDirk van der Merwe <dirk.vandermerwe@netronome.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 16848c8a
......@@ -294,6 +294,9 @@ static int nfp_pcie_sriov_disable(struct pci_dev *pdev)
static int nfp_pcie_sriov_configure(struct pci_dev *pdev, int num_vfs)
{
if (!pci_get_drvdata(pdev))
return -ENOENT;
if (num_vfs == 0)
return nfp_pcie_sriov_disable(pdev);
else
......@@ -720,9 +723,13 @@ static int nfp_pci_probe(struct pci_dev *pdev,
return err;
}
static void nfp_pci_remove(struct pci_dev *pdev)
static void __nfp_pci_shutdown(struct pci_dev *pdev, bool unload_fw)
{
struct nfp_pf *pf = pci_get_drvdata(pdev);
struct nfp_pf *pf;
pf = pci_get_drvdata(pdev);
if (!pf)
return;
nfp_hwmon_unregister(pf);
......@@ -733,7 +740,7 @@ static void nfp_pci_remove(struct pci_dev *pdev)
vfree(pf->dumpspec);
kfree(pf->rtbl);
nfp_mip_close(pf->mip);
if (pf->fw_loaded)
if (unload_fw && pf->fw_loaded)
nfp_fw_unload(pf);
destroy_workqueue(pf->wq);
......@@ -749,11 +756,22 @@ static void nfp_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
static void nfp_pci_remove(struct pci_dev *pdev)
{
__nfp_pci_shutdown(pdev, true);
}
static void nfp_pci_shutdown(struct pci_dev *pdev)
{
__nfp_pci_shutdown(pdev, false);
}
static struct pci_driver nfp_pci_driver = {
.name = nfp_driver_name,
.id_table = nfp_pci_device_ids,
.probe = nfp_pci_probe,
.remove = nfp_pci_remove,
.shutdown = nfp_pci_shutdown,
.sriov_configure = nfp_pcie_sriov_configure,
};
......
......@@ -282,8 +282,14 @@ static int nfp_netvf_pci_probe(struct pci_dev *pdev,
static void nfp_netvf_pci_remove(struct pci_dev *pdev)
{
struct nfp_net_vf *vf = pci_get_drvdata(pdev);
struct nfp_net *nn = vf->nn;
struct nfp_net_vf *vf;
struct nfp_net *nn;
vf = pci_get_drvdata(pdev);
if (!vf)
return;
nn = vf->nn;
/* Note, the order is slightly different from above as we need
* to keep the nn pointer around till we have freed everything.
......@@ -317,4 +323,5 @@ struct pci_driver nfp_netvf_pci_driver = {
.id_table = nfp_netvf_pci_device_ids,
.probe = nfp_netvf_pci_probe,
.remove = nfp_netvf_pci_remove,
.shutdown = nfp_netvf_pci_remove,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment