Merge branch 'pci/virtualization' into next
* pci/virtualization: PCI: Remove __pci_dev_reset() and pci_dev_reset() PCI: Split ->reset_notify() method into ->reset_prepare() and ->reset_done() PCI: Protect pci_error_handlers->reset_notify() usage with device_lock() PCI: Protect pci_driver->sriov_configure() usage with device_lock() PCI: Mark Intel XXV710 NIC INTx masking as broken PCI: Restore PRI and PASID state after Function-Level Reset PCI: Cache PRI and PASID bits in pci_dev
This commit is contained in:
commit
bb02ce95a5
|
@ -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[] = {
|
||||
|
|
|
@ -153,23 +153,27 @@ int pci_enable_pri(struct pci_dev *pdev, u32 reqs)
|
|||
u32 max_requests;
|
||||
int pos;
|
||||
|
||||
if (WARN_ON(pdev->pri_enabled))
|
||||
return -EBUSY;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
|
||||
if (!pos)
|
||||
return -EINVAL;
|
||||
|
||||
pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
|
||||
pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
|
||||
if ((control & PCI_PRI_CTRL_ENABLE) ||
|
||||
!(status & PCI_PRI_STATUS_STOPPED))
|
||||
if (!(status & PCI_PRI_STATUS_STOPPED))
|
||||
return -EBUSY;
|
||||
|
||||
pci_read_config_dword(pdev, pos + PCI_PRI_MAX_REQ, &max_requests);
|
||||
reqs = min(max_requests, reqs);
|
||||
pdev->pri_reqs_alloc = reqs;
|
||||
pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
|
||||
|
||||
control |= PCI_PRI_CTRL_ENABLE;
|
||||
control = PCI_PRI_CTRL_ENABLE;
|
||||
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
|
||||
|
||||
pdev->pri_enabled = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_enable_pri);
|
||||
|
@ -185,6 +189,9 @@ void pci_disable_pri(struct pci_dev *pdev)
|
|||
u16 control;
|
||||
int pos;
|
||||
|
||||
if (WARN_ON(!pdev->pri_enabled))
|
||||
return;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
|
||||
if (!pos)
|
||||
return;
|
||||
|
@ -192,9 +199,33 @@ void pci_disable_pri(struct pci_dev *pdev)
|
|||
pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
|
||||
control &= ~PCI_PRI_CTRL_ENABLE;
|
||||
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
|
||||
|
||||
pdev->pri_enabled = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_disable_pri);
|
||||
|
||||
/**
|
||||
* pci_restore_pri_state - Restore PRI
|
||||
* @pdev: PCI device structure
|
||||
*/
|
||||
void pci_restore_pri_state(struct pci_dev *pdev)
|
||||
{
|
||||
u16 control = PCI_PRI_CTRL_ENABLE;
|
||||
u32 reqs = pdev->pri_reqs_alloc;
|
||||
int pos;
|
||||
|
||||
if (!pdev->pri_enabled)
|
||||
return;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
pci_write_config_dword(pdev, pos + PCI_PRI_ALLOC_REQ, reqs);
|
||||
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_restore_pri_state);
|
||||
|
||||
/**
|
||||
* pci_reset_pri - Resets device's PRI state
|
||||
* @pdev: PCI device structure
|
||||
|
@ -207,16 +238,14 @@ int pci_reset_pri(struct pci_dev *pdev)
|
|||
u16 control;
|
||||
int pos;
|
||||
|
||||
if (WARN_ON(pdev->pri_enabled))
|
||||
return -EBUSY;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
|
||||
if (!pos)
|
||||
return -EINVAL;
|
||||
|
||||
pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
|
||||
if (control & PCI_PRI_CTRL_ENABLE)
|
||||
return -EBUSY;
|
||||
|
||||
control |= PCI_PRI_CTRL_RESET;
|
||||
|
||||
control = PCI_PRI_CTRL_RESET;
|
||||
pci_write_config_word(pdev, pos + PCI_PRI_CTRL, control);
|
||||
|
||||
return 0;
|
||||
|
@ -239,16 +268,14 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
|
|||
u16 control, supported;
|
||||
int pos;
|
||||
|
||||
if (WARN_ON(pdev->pasid_enabled))
|
||||
return -EBUSY;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
|
||||
if (!pos)
|
||||
return -EINVAL;
|
||||
|
||||
pci_read_config_word(pdev, pos + PCI_PASID_CTRL, &control);
|
||||
pci_read_config_word(pdev, pos + PCI_PASID_CAP, &supported);
|
||||
|
||||
if (control & PCI_PASID_CTRL_ENABLE)
|
||||
return -EINVAL;
|
||||
|
||||
supported &= PCI_PASID_CAP_EXEC | PCI_PASID_CAP_PRIV;
|
||||
|
||||
/* User wants to enable anything unsupported? */
|
||||
|
@ -256,9 +283,12 @@ int pci_enable_pasid(struct pci_dev *pdev, int features)
|
|||
return -EINVAL;
|
||||
|
||||
control = PCI_PASID_CTRL_ENABLE | features;
|
||||
pdev->pasid_features = features;
|
||||
|
||||
pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
|
||||
|
||||
pdev->pasid_enabled = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_enable_pasid);
|
||||
|
@ -266,21 +296,46 @@ EXPORT_SYMBOL_GPL(pci_enable_pasid);
|
|||
/**
|
||||
* pci_disable_pasid - Disable the PASID capability
|
||||
* @pdev: PCI device structure
|
||||
*
|
||||
*/
|
||||
void pci_disable_pasid(struct pci_dev *pdev)
|
||||
{
|
||||
u16 control = 0;
|
||||
int pos;
|
||||
|
||||
if (WARN_ON(!pdev->pasid_enabled))
|
||||
return;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
|
||||
|
||||
pdev->pasid_enabled = 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_disable_pasid);
|
||||
|
||||
/**
|
||||
* pci_restore_pasid_state - Restore PASID capabilities
|
||||
* @pdev: PCI device structure
|
||||
*/
|
||||
void pci_restore_pasid_state(struct pci_dev *pdev)
|
||||
{
|
||||
u16 control;
|
||||
int pos;
|
||||
|
||||
if (!pdev->pasid_enabled)
|
||||
return;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PASID);
|
||||
if (!pos)
|
||||
return;
|
||||
|
||||
control = PCI_PASID_CTRL_ENABLE | pdev->pasid_features;
|
||||
pci_write_config_word(pdev, pos + PCI_PASID_CTRL, control);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_restore_pasid_state);
|
||||
|
||||
/**
|
||||
* pci_pasid_features - Check which PASID features are supported
|
||||
* @pdev: PCI device structure
|
||||
|
|
|
@ -461,8 +461,6 @@ found:
|
|||
else
|
||||
iov->dev = dev;
|
||||
|
||||
mutex_init(&iov->lock);
|
||||
|
||||
dev->sriov = iov;
|
||||
dev->is_physfn = 1;
|
||||
rc = compute_max_vf_buses(dev);
|
||||
|
@ -491,8 +489,6 @@ static void sriov_release(struct pci_dev *dev)
|
|||
if (dev != dev->sriov->dev)
|
||||
pci_dev_put(dev->sriov->dev);
|
||||
|
||||
mutex_destroy(&dev->sriov->lock);
|
||||
|
||||
kfree(dev->sriov);
|
||||
dev->sriov = NULL;
|
||||
}
|
||||
|
|
|
@ -595,7 +595,6 @@ static ssize_t sriov_numvfs_store(struct device *dev,
|
|||
const char *buf, size_t count)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct pci_sriov *iov = pdev->sriov;
|
||||
int ret;
|
||||
u16 num_vfs;
|
||||
|
||||
|
@ -606,7 +605,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
|
|||
if (num_vfs > pci_sriov_get_totalvfs(pdev))
|
||||
return -ERANGE;
|
||||
|
||||
mutex_lock(&iov->dev->sriov->lock);
|
||||
device_lock(&pdev->dev);
|
||||
|
||||
if (num_vfs == pdev->sriov->num_VFs)
|
||||
goto exit;
|
||||
|
@ -641,7 +640,7 @@ static ssize_t sriov_numvfs_store(struct device *dev,
|
|||
num_vfs, ret);
|
||||
|
||||
exit:
|
||||
mutex_unlock(&iov->dev->sriov->lock);
|
||||
device_unlock(&pdev->dev);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <linux/pm_runtime.h>
|
||||
#include <linux/pci_hotplug.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/pci-ats.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/dma.h>
|
||||
#include <linux/aer.h>
|
||||
|
@ -1173,6 +1174,8 @@ void pci_restore_state(struct pci_dev *dev)
|
|||
|
||||
/* PCI Express register must be restored first */
|
||||
pci_restore_pcie_state(dev);
|
||||
pci_restore_pasid_state(dev);
|
||||
pci_restore_pri_state(dev);
|
||||
pci_restore_ats_state(dev);
|
||||
pci_restore_vc_state(dev);
|
||||
|
||||
|
@ -4033,40 +4036,6 @@ static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe)
|
|||
return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
|
||||
}
|
||||
|
||||
static int __pci_dev_reset(struct pci_dev *dev, int probe)
|
||||
{
|
||||
int rc;
|
||||
|
||||
might_sleep();
|
||||
|
||||
rc = pci_dev_specific_reset(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
if (pcie_has_flr(dev)) {
|
||||
if (!probe)
|
||||
pcie_flr(dev);
|
||||
rc = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = pci_af_flr(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
rc = pci_pm_reset(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
rc = pci_dev_reset_slot_function(dev, probe);
|
||||
if (rc != -ENOTTY)
|
||||
goto done;
|
||||
|
||||
rc = pci_parent_bus_reset(dev, probe);
|
||||
done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void pci_dev_lock(struct pci_dev *dev)
|
||||
{
|
||||
pci_cfg_access_lock(dev);
|
||||
|
@ -4092,26 +4061,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;
|
||||
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);
|
||||
/*
|
||||
* 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_prepare)
|
||||
err_handler->reset_prepare(dev);
|
||||
|
||||
/*
|
||||
* Wake-up device prior to save. PM registers default to D0 after
|
||||
|
@ -4133,23 +4094,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);
|
||||
}
|
||||
|
||||
static int pci_dev_reset(struct pci_dev *dev, int probe)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!probe)
|
||||
pci_dev_lock(dev);
|
||||
|
||||
rc = __pci_dev_reset(dev, probe);
|
||||
|
||||
if (!probe)
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
return rc;
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4171,7 +4127,13 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
|
|||
*/
|
||||
int __pci_reset_function(struct pci_dev *dev)
|
||||
{
|
||||
return pci_dev_reset(dev, 0);
|
||||
int ret;
|
||||
|
||||
pci_dev_lock(dev);
|
||||
ret = __pci_reset_function_locked(dev);
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__pci_reset_function);
|
||||
|
||||
|
@ -4196,7 +4158,27 @@ EXPORT_SYMBOL_GPL(__pci_reset_function);
|
|||
*/
|
||||
int __pci_reset_function_locked(struct pci_dev *dev)
|
||||
{
|
||||
return __pci_dev_reset(dev, 0);
|
||||
int rc;
|
||||
|
||||
might_sleep();
|
||||
|
||||
rc = pci_dev_specific_reset(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
if (pcie_has_flr(dev)) {
|
||||
pcie_flr(dev);
|
||||
return 0;
|
||||
}
|
||||
rc = pci_af_flr(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_pm_reset(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_dev_reset_slot_function(dev, 0);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
return pci_parent_bus_reset(dev, 0);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
|
||||
|
||||
|
@ -4213,7 +4195,26 @@ EXPORT_SYMBOL_GPL(__pci_reset_function_locked);
|
|||
*/
|
||||
int pci_probe_reset_function(struct pci_dev *dev)
|
||||
{
|
||||
return pci_dev_reset(dev, 1);
|
||||
int rc;
|
||||
|
||||
might_sleep();
|
||||
|
||||
rc = pci_dev_specific_reset(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
if (pcie_has_flr(dev))
|
||||
return 0;
|
||||
rc = pci_af_flr(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_pm_reset(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
rc = pci_dev_reset_slot_function(dev, 1);
|
||||
if (rc != -ENOTTY)
|
||||
return rc;
|
||||
|
||||
return pci_parent_bus_reset(dev, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4236,15 +4237,17 @@ int pci_reset_function(struct pci_dev *dev)
|
|||
{
|
||||
int rc;
|
||||
|
||||
rc = pci_dev_reset(dev, 1);
|
||||
rc = pci_probe_reset_function(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
pci_dev_lock(dev);
|
||||
pci_dev_save_and_disable(dev);
|
||||
|
||||
rc = pci_dev_reset(dev, 0);
|
||||
rc = __pci_reset_function_locked(dev);
|
||||
|
||||
pci_dev_restore(dev);
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -4260,20 +4263,18 @@ int pci_try_reset_function(struct pci_dev *dev)
|
|||
{
|
||||
int rc;
|
||||
|
||||
rc = pci_dev_reset(dev, 1);
|
||||
rc = pci_probe_reset_function(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
pci_dev_save_and_disable(dev);
|
||||
if (!pci_dev_trylock(dev))
|
||||
return -EAGAIN;
|
||||
|
||||
if (pci_dev_trylock(dev)) {
|
||||
rc = __pci_dev_reset(dev, 0);
|
||||
pci_dev_unlock(dev);
|
||||
} else
|
||||
rc = -EAGAIN;
|
||||
pci_dev_save_and_disable(dev);
|
||||
rc = __pci_reset_function_locked(dev);
|
||||
pci_dev_unlock(dev);
|
||||
|
||||
pci_dev_restore(dev);
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_try_reset_function);
|
||||
|
@ -4423,7 +4424,9 @@ static void pci_bus_save_and_disable(struct pci_bus *bus)
|
|||
struct pci_dev *dev;
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pci_dev_lock(dev);
|
||||
pci_dev_save_and_disable(dev);
|
||||
pci_dev_unlock(dev);
|
||||
if (dev->subordinate)
|
||||
pci_bus_save_and_disable(dev->subordinate);
|
||||
}
|
||||
|
@ -4438,7 +4441,9 @@ static void pci_bus_restore(struct pci_bus *bus)
|
|||
struct pci_dev *dev;
|
||||
|
||||
list_for_each_entry(dev, &bus->devices, bus_list) {
|
||||
pci_dev_lock(dev);
|
||||
pci_dev_restore(dev);
|
||||
pci_dev_unlock(dev);
|
||||
if (dev->subordinate)
|
||||
pci_bus_restore(dev->subordinate);
|
||||
}
|
||||
|
|
|
@ -272,7 +272,6 @@ struct pci_sriov {
|
|||
u16 driver_max_VFs; /* max num VFs driver supports */
|
||||
struct pci_dev *dev; /* lowest numbered PF */
|
||||
struct pci_dev *self; /* this PF */
|
||||
struct mutex lock; /* lock for setting sriov_numvfs in sysfs */
|
||||
resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
|
||||
bool drivers_autoprobe; /* auto probing of VFs by driver */
|
||||
};
|
||||
|
|
|
@ -3249,6 +3249,10 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1588,
|
|||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x1589,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x158a,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x158b,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d0,
|
||||
quirk_broken_intx_masking);
|
||||
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x37d1,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
int pci_enable_pri(struct pci_dev *pdev, u32 reqs);
|
||||
void pci_disable_pri(struct pci_dev *pdev);
|
||||
void pci_restore_pri_state(struct pci_dev *pdev);
|
||||
int pci_reset_pri(struct pci_dev *pdev);
|
||||
|
||||
#else /* CONFIG_PCI_PRI */
|
||||
|
@ -20,6 +21,10 @@ static inline void pci_disable_pri(struct pci_dev *pdev)
|
|||
{
|
||||
}
|
||||
|
||||
static inline void pci_restore_pri_state(struct pci_dev *pdev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int pci_reset_pri(struct pci_dev *pdev)
|
||||
{
|
||||
return -ENODEV;
|
||||
|
@ -31,6 +36,7 @@ static inline int pci_reset_pri(struct pci_dev *pdev)
|
|||
|
||||
int pci_enable_pasid(struct pci_dev *pdev, int features);
|
||||
void pci_disable_pasid(struct pci_dev *pdev);
|
||||
void pci_restore_pasid_state(struct pci_dev *pdev);
|
||||
int pci_pasid_features(struct pci_dev *pdev);
|
||||
int pci_max_pasids(struct pci_dev *pdev);
|
||||
|
||||
|
@ -45,6 +51,10 @@ static inline void pci_disable_pasid(struct pci_dev *pdev)
|
|||
{
|
||||
}
|
||||
|
||||
static inline void pci_restore_pasid_state(struct pci_dev *pdev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int pci_pasid_features(struct pci_dev *pdev)
|
||||
{
|
||||
return -EINVAL;
|
||||
|
|
|
@ -361,6 +361,8 @@ struct pci_dev {
|
|||
unsigned int msix_enabled:1;
|
||||
unsigned int ari_enabled:1; /* ARI forwarding */
|
||||
unsigned int ats_enabled:1; /* Address Translation Service */
|
||||
unsigned int pasid_enabled:1; /* Process Address Space ID */
|
||||
unsigned int pri_enabled:1; /* Page Request Interface */
|
||||
unsigned int is_managed:1;
|
||||
unsigned int needs_freset:1; /* Dev requires fundamental reset */
|
||||
unsigned int state_saved:1;
|
||||
|
@ -403,6 +405,12 @@ struct pci_dev {
|
|||
u16 ats_cap; /* ATS Capability offset */
|
||||
u8 ats_stu; /* ATS Smallest Translation Unit */
|
||||
atomic_t ats_ref_cnt; /* number of VFs with ATS enabled */
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_PRI
|
||||
u32 pri_reqs_alloc; /* Number of PRI requests allocated */
|
||||
#endif
|
||||
#ifdef CONFIG_PCI_PASID
|
||||
u16 pasid_features;
|
||||
#endif
|
||||
phys_addr_t rom; /* Physical address of ROM if it's not from the BAR */
|
||||
size_t romlen; /* Length of ROM if it's not from the BAR */
|
||||
|
@ -695,7 +703,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