Merge branch 'pci/virtualization' into next
* pci/virtualization: ixgbe: Use pcie_flr() instead of duplicating it IB/hfi1: Use pcie_flr() instead of duplicating it PCI: Call pcie_flr() from reset_chelsio_generic_dev() PCI: Call pcie_flr() from reset_intel_82599_sfp_virtfn() PCI: Export pcie_flr() PCI: Add sysfs sriov_drivers_autoprobe to control VF driver binding PCI: Avoid FLR for Intel 82579 NICs Conflicts: include/linux/pci.h
This commit is contained in:
commit
ef1b5dad5a
|
@ -301,3 +301,25 @@ Contact: Emil Velikov <emil.l.velikov@gmail.com>
|
||||||
Description:
|
Description:
|
||||||
This file contains the revision field of the the PCI device.
|
This file contains the revision field of the the PCI device.
|
||||||
The value comes from device config space. The file is read only.
|
The value comes from device config space. The file is read only.
|
||||||
|
|
||||||
|
What: /sys/bus/pci/devices/.../sriov_drivers_autoprobe
|
||||||
|
Date: April 2017
|
||||||
|
Contact: Bodong Wang<bodong@mellanox.com>
|
||||||
|
Description:
|
||||||
|
This file is associated with the PF of a device that
|
||||||
|
supports SR-IOV. It determines whether newly-enabled VFs
|
||||||
|
are immediately bound to a driver. It initially contains
|
||||||
|
1, which means the kernel automatically binds VFs to a
|
||||||
|
compatible driver immediately after they are enabled. If
|
||||||
|
an application writes 0 to the file before enabling VFs,
|
||||||
|
the kernel will not bind VFs to a driver.
|
||||||
|
|
||||||
|
A typical use case is to write 0 to this file, then enable
|
||||||
|
VFs, then assign the newly-created VFs to virtual machines.
|
||||||
|
Note that changing this file does not affect already-
|
||||||
|
enabled VFs. In this scenario, the user must first disable
|
||||||
|
the VFs, write 0 to sriov_drivers_autoprobe, then re-enable
|
||||||
|
the VFs.
|
||||||
|
|
||||||
|
This is similar to /sys/bus/pci/drivers_autoprobe, but
|
||||||
|
affects only the VFs associated with a specific PF.
|
||||||
|
|
|
@ -68,6 +68,18 @@ To disable SR-IOV capability:
|
||||||
echo 0 > \
|
echo 0 > \
|
||||||
/sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
|
/sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_numvfs
|
||||||
|
|
||||||
|
To enable auto probing VFs by a compatible driver on the host, run
|
||||||
|
command below before enabling SR-IOV capabilities. This is the
|
||||||
|
default behavior.
|
||||||
|
echo 1 > \
|
||||||
|
/sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe
|
||||||
|
|
||||||
|
To disable auto probing VFs by a compatible driver on the host, run
|
||||||
|
command below before enabling SR-IOV capabilities. Updating this
|
||||||
|
entry will not affect VFs which are already probed.
|
||||||
|
echo 0 > \
|
||||||
|
/sys/bus/pci/devices/<DOMAIN:BUS:DEVICE.FUNCTION>/sriov_drivers_autoprobe
|
||||||
|
|
||||||
3.2 Usage example
|
3.2 Usage example
|
||||||
|
|
||||||
Following piece of code illustrates the usage of the SR-IOV API.
|
Following piece of code illustrates the usage of the SR-IOV API.
|
||||||
|
|
|
@ -13610,14 +13610,14 @@ static void init_chip(struct hfi1_devdata *dd)
|
||||||
dd_dev_info(dd, "Resetting CSRs with FLR\n");
|
dd_dev_info(dd, "Resetting CSRs with FLR\n");
|
||||||
|
|
||||||
/* do the FLR, the DC reset will remain */
|
/* do the FLR, the DC reset will remain */
|
||||||
hfi1_pcie_flr(dd);
|
pcie_flr(dd->pcidev);
|
||||||
|
|
||||||
/* restore command and BARs */
|
/* restore command and BARs */
|
||||||
restore_pci_variables(dd);
|
restore_pci_variables(dd);
|
||||||
|
|
||||||
if (is_ax(dd)) {
|
if (is_ax(dd)) {
|
||||||
dd_dev_info(dd, "Resetting CSRs with FLR\n");
|
dd_dev_info(dd, "Resetting CSRs with FLR\n");
|
||||||
hfi1_pcie_flr(dd);
|
pcie_flr(dd->pcidev);
|
||||||
restore_pci_variables(dd);
|
restore_pci_variables(dd);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1764,7 +1764,6 @@ int hfi1_pcie_init(struct pci_dev *, const struct pci_device_id *);
|
||||||
void hfi1_pcie_cleanup(struct pci_dev *);
|
void hfi1_pcie_cleanup(struct pci_dev *);
|
||||||
int hfi1_pcie_ddinit(struct hfi1_devdata *, struct pci_dev *);
|
int hfi1_pcie_ddinit(struct hfi1_devdata *, struct pci_dev *);
|
||||||
void hfi1_pcie_ddcleanup(struct hfi1_devdata *);
|
void hfi1_pcie_ddcleanup(struct hfi1_devdata *);
|
||||||
void hfi1_pcie_flr(struct hfi1_devdata *);
|
|
||||||
int pcie_speeds(struct hfi1_devdata *);
|
int pcie_speeds(struct hfi1_devdata *);
|
||||||
void request_msix(struct hfi1_devdata *, u32 *, struct hfi1_msix_entry *);
|
void request_msix(struct hfi1_devdata *, u32 *, struct hfi1_msix_entry *);
|
||||||
void hfi1_enable_intx(struct pci_dev *);
|
void hfi1_enable_intx(struct pci_dev *);
|
||||||
|
|
|
@ -240,36 +240,6 @@ void hfi1_pcie_ddcleanup(struct hfi1_devdata *dd)
|
||||||
iounmap(dd->piobase);
|
iounmap(dd->piobase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Do a Function Level Reset (FLR) on the device.
|
|
||||||
* Based on static function drivers/pci/pci.c:pcie_flr().
|
|
||||||
*/
|
|
||||||
void hfi1_pcie_flr(struct hfi1_devdata *dd)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
u16 status;
|
|
||||||
|
|
||||||
/* no need to check for the capability - we know the device has it */
|
|
||||||
|
|
||||||
/* wait for Transaction Pending bit to clear, at most a few ms */
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (i)
|
|
||||||
msleep((1 << (i - 1)) * 100);
|
|
||||||
|
|
||||||
pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVSTA, &status);
|
|
||||||
if (!(status & PCI_EXP_DEVSTA_TRPND))
|
|
||||||
goto clear;
|
|
||||||
}
|
|
||||||
|
|
||||||
dd_dev_err(dd, "Transaction Pending bit is not clearing, proceeding with reset anyway\n");
|
|
||||||
|
|
||||||
clear:
|
|
||||||
pcie_capability_set_word(dd->pcidev, PCI_EXP_DEVCTL,
|
|
||||||
PCI_EXP_DEVCTL_BCR_FLR);
|
|
||||||
/* PCIe spec requires the function to be back within 100ms */
|
|
||||||
msleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void msix_setup(struct hfi1_devdata *dd, int pos, u32 *msixcnt,
|
static void msix_setup(struct hfi1_devdata *dd, int pos, u32 *msixcnt,
|
||||||
struct hfi1_msix_entry *hfi1_msix_entry)
|
struct hfi1_msix_entry *hfi1_msix_entry)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7112,18 +7112,6 @@ static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_IOV
|
#ifdef CONFIG_PCI_IOV
|
||||||
static inline void ixgbe_issue_vf_flr(struct ixgbe_adapter *adapter,
|
|
||||||
struct pci_dev *vfdev)
|
|
||||||
{
|
|
||||||
if (!pci_wait_for_pending_transaction(vfdev))
|
|
||||||
e_dev_warn("Issuing VFLR with pending transactions\n");
|
|
||||||
|
|
||||||
e_dev_err("Issuing VFLR for VF %s\n", pci_name(vfdev));
|
|
||||||
pcie_capability_set_word(vfdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
|
||||||
|
|
||||||
msleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
|
static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct ixgbe_hw *hw = &adapter->hw;
|
struct ixgbe_hw *hw = &adapter->hw;
|
||||||
|
@ -7156,7 +7144,7 @@ static void ixgbe_check_for_bad_vf(struct ixgbe_adapter *adapter)
|
||||||
pci_read_config_word(vfdev, PCI_STATUS, &status_reg);
|
pci_read_config_word(vfdev, PCI_STATUS, &status_reg);
|
||||||
if (status_reg != IXGBE_FAILED_READ_CFG_WORD &&
|
if (status_reg != IXGBE_FAILED_READ_CFG_WORD &&
|
||||||
status_reg & PCI_STATUS_REC_MASTER_ABORT)
|
status_reg & PCI_STATUS_REC_MASTER_ABORT)
|
||||||
ixgbe_issue_vf_flr(adapter, vfdev);
|
pcie_flr(vfdev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10244,7 +10232,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
|
||||||
* VFLR. Just clean up the AER in that case.
|
* VFLR. Just clean up the AER in that case.
|
||||||
*/
|
*/
|
||||||
if (vfdev) {
|
if (vfdev) {
|
||||||
ixgbe_issue_vf_flr(adapter, vfdev);
|
pcie_flr(vfdev);
|
||||||
/* Free device reference count */
|
/* Free device reference count */
|
||||||
pci_dev_put(vfdev);
|
pci_dev_put(vfdev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -450,6 +450,7 @@ found:
|
||||||
iov->total_VFs = total;
|
iov->total_VFs = total;
|
||||||
iov->pgsz = pgsz;
|
iov->pgsz = pgsz;
|
||||||
iov->self = dev;
|
iov->self = dev;
|
||||||
|
iov->drivers_autoprobe = true;
|
||||||
pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
|
pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
|
||||||
pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
|
pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
|
||||||
if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)
|
if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END)
|
||||||
|
|
|
@ -394,6 +394,18 @@ void __weak pcibios_free_irq(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI_IOV
|
||||||
|
static inline bool pci_device_can_probe(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
return (!pdev->is_virtfn || pdev->physfn->sriov->drivers_autoprobe);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline bool pci_device_can_probe(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int pci_device_probe(struct device *dev)
|
static int pci_device_probe(struct device *dev)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
@ -405,10 +417,12 @@ static int pci_device_probe(struct device *dev)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
pci_dev_get(pci_dev);
|
pci_dev_get(pci_dev);
|
||||||
error = __pci_device_probe(drv, pci_dev);
|
if (pci_device_can_probe(pci_dev)) {
|
||||||
if (error) {
|
error = __pci_device_probe(drv, pci_dev);
|
||||||
pcibios_free_irq(pci_dev);
|
if (error) {
|
||||||
pci_dev_put(pci_dev);
|
pcibios_free_irq(pci_dev);
|
||||||
|
pci_dev_put(pci_dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
|
|
@ -526,10 +526,37 @@ exit:
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t sriov_drivers_autoprobe_show(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = to_pci_dev(dev);
|
||||||
|
|
||||||
|
return sprintf(buf, "%u\n", pdev->sriov->drivers_autoprobe);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t sriov_drivers_autoprobe_store(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
struct pci_dev *pdev = to_pci_dev(dev);
|
||||||
|
bool drivers_autoprobe;
|
||||||
|
|
||||||
|
if (kstrtobool(buf, &drivers_autoprobe) < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
pdev->sriov->drivers_autoprobe = drivers_autoprobe;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs);
|
static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs);
|
||||||
static struct device_attribute sriov_numvfs_attr =
|
static struct device_attribute sriov_numvfs_attr =
|
||||||
__ATTR(sriov_numvfs, (S_IRUGO|S_IWUSR|S_IWGRP),
|
__ATTR(sriov_numvfs, (S_IRUGO|S_IWUSR|S_IWGRP),
|
||||||
sriov_numvfs_show, sriov_numvfs_store);
|
sriov_numvfs_show, sriov_numvfs_store);
|
||||||
|
static struct device_attribute sriov_drivers_autoprobe_attr =
|
||||||
|
__ATTR(sriov_drivers_autoprobe, (S_IRUGO|S_IWUSR|S_IWGRP),
|
||||||
|
sriov_drivers_autoprobe_show, sriov_drivers_autoprobe_store);
|
||||||
#endif /* CONFIG_PCI_IOV */
|
#endif /* CONFIG_PCI_IOV */
|
||||||
|
|
||||||
static ssize_t driver_override_store(struct device *dev,
|
static ssize_t driver_override_store(struct device *dev,
|
||||||
|
@ -1539,6 +1566,7 @@ static struct attribute_group pci_dev_hp_attr_group = {
|
||||||
static struct attribute *sriov_dev_attrs[] = {
|
static struct attribute *sriov_dev_attrs[] = {
|
||||||
&sriov_totalvfs_attr.attr,
|
&sriov_totalvfs_attr.attr,
|
||||||
&sriov_numvfs_attr.attr,
|
&sriov_numvfs_attr.attr,
|
||||||
|
&sriov_drivers_autoprobe_attr.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3860,24 +3860,41 @@ static void pci_flr_wait(struct pci_dev *dev)
|
||||||
(i - 1) * 100);
|
(i - 1) * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pcie_flr(struct pci_dev *dev, int probe)
|
/**
|
||||||
|
* pcie_has_flr - check if a device supports function level resets
|
||||||
|
* @dev: device to check
|
||||||
|
*
|
||||||
|
* Returns true if the device advertises support for PCIe function level
|
||||||
|
* resets.
|
||||||
|
*/
|
||||||
|
static bool pcie_has_flr(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
u32 cap;
|
u32 cap;
|
||||||
|
|
||||||
|
if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
|
||||||
|
return false;
|
||||||
|
|
||||||
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
|
pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap);
|
||||||
if (!(cap & PCI_EXP_DEVCAP_FLR))
|
return cap & PCI_EXP_DEVCAP_FLR;
|
||||||
return -ENOTTY;
|
}
|
||||||
|
|
||||||
if (probe)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcie_flr - initiate a PCIe function level reset
|
||||||
|
* @dev: device to reset
|
||||||
|
*
|
||||||
|
* Initiate a function level reset on @dev. The caller should ensure the
|
||||||
|
* device supports FLR before calling this function, e.g. by using the
|
||||||
|
* pcie_has_flr() helper.
|
||||||
|
*/
|
||||||
|
void pcie_flr(struct pci_dev *dev)
|
||||||
|
{
|
||||||
if (!pci_wait_for_pending_transaction(dev))
|
if (!pci_wait_for_pending_transaction(dev))
|
||||||
dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
|
dev_err(&dev->dev, "timed out waiting for pending transaction; performing function level reset anyway\n");
|
||||||
|
|
||||||
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
||||||
pci_flr_wait(dev);
|
pci_flr_wait(dev);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(pcie_flr);
|
||||||
|
|
||||||
static int pci_af_flr(struct pci_dev *dev, int probe)
|
static int pci_af_flr(struct pci_dev *dev, int probe)
|
||||||
{
|
{
|
||||||
|
@ -3888,6 +3905,9 @@ static int pci_af_flr(struct pci_dev *dev, int probe)
|
||||||
if (!pos)
|
if (!pos)
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
|
if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET)
|
||||||
|
return -ENOTTY;
|
||||||
|
|
||||||
pci_read_config_byte(dev, pos + PCI_AF_CAP, &cap);
|
pci_read_config_byte(dev, pos + PCI_AF_CAP, &cap);
|
||||||
if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
|
if (!(cap & PCI_AF_CAP_TP) || !(cap & PCI_AF_CAP_FLR))
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
@ -4058,9 +4078,12 @@ static int __pci_dev_reset(struct pci_dev *dev, int probe)
|
||||||
if (rc != -ENOTTY)
|
if (rc != -ENOTTY)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
rc = pcie_flr(dev, probe);
|
if (pcie_has_flr(dev)) {
|
||||||
if (rc != -ENOTTY)
|
if (!probe)
|
||||||
|
pcie_flr(dev);
|
||||||
|
rc = 0;
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
rc = pci_af_flr(dev, probe);
|
rc = pci_af_flr(dev, probe);
|
||||||
if (rc != -ENOTTY)
|
if (rc != -ENOTTY)
|
||||||
|
|
|
@ -272,6 +272,7 @@ struct pci_sriov {
|
||||||
struct pci_dev *self; /* this PF */
|
struct pci_dev *self; /* this PF */
|
||||||
struct mutex lock; /* lock for setting sriov_numvfs in sysfs */
|
struct mutex lock; /* lock for setting sriov_numvfs in sysfs */
|
||||||
resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
|
resource_size_t barsz[PCI_SRIOV_NUM_BARS]; /* VF BAR size */
|
||||||
|
bool drivers_autoprobe; /* auto probing of VFs by driver */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* pci_dev priv_flags */
|
/* pci_dev priv_flags */
|
||||||
|
|
|
@ -3666,19 +3666,11 @@ static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe)
|
||||||
*
|
*
|
||||||
* The 82599 supports FLR on VFs, but FLR support is reported only
|
* The 82599 supports FLR on VFs, but FLR support is reported only
|
||||||
* in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
|
* in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5).
|
||||||
* Therefore, we can't use pcie_flr(), which checks the VF DEVCAP.
|
* Thus we must call pcie_flr() directly without first checking if it is
|
||||||
|
* supported.
|
||||||
*/
|
*/
|
||||||
|
if (!probe)
|
||||||
if (probe)
|
pcie_flr(dev);
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!pci_wait_for_pending_transaction(dev))
|
|
||||||
dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
|
|
||||||
|
|
||||||
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
|
||||||
|
|
||||||
msleep(100);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3783,20 +3775,7 @@ static int reset_chelsio_generic_dev(struct pci_dev *dev, int probe)
|
||||||
PCI_MSIX_FLAGS_ENABLE |
|
PCI_MSIX_FLAGS_ENABLE |
|
||||||
PCI_MSIX_FLAGS_MASKALL);
|
PCI_MSIX_FLAGS_MASKALL);
|
||||||
|
|
||||||
/*
|
pcie_flr(dev);
|
||||||
* Start of pcie_flr() code sequence. This reset code is a copy of
|
|
||||||
* the guts of pcie_flr() because that's not an exported function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!pci_wait_for_pending_transaction(dev))
|
|
||||||
dev_err(&dev->dev, "transaction is not cleared; proceeding with reset anyway\n");
|
|
||||||
|
|
||||||
pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR);
|
|
||||||
msleep(100);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* End of pcie_flr() code sequence.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Restore the configuration information (BAR values, etc.) including
|
* Restore the configuration information (BAR values, etc.) including
|
||||||
|
@ -4677,3 +4656,11 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2030, quirk_no_aersid);
|
||||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid);
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2031, quirk_no_aersid);
|
||||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid);
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2032, quirk_no_aersid);
|
||||||
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x2033, quirk_no_aersid);
|
||||||
|
|
||||||
|
/* FLR may cause some 82579 devices to hang. */
|
||||||
|
static void quirk_intel_no_flr(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
dev->dev_flags |= PCI_DEV_FLAGS_NO_FLR_RESET;
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1502, quirk_intel_no_flr);
|
||||||
|
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x1503, quirk_intel_no_flr);
|
||||||
|
|
|
@ -181,6 +181,8 @@ enum pci_dev_flags {
|
||||||
PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8),
|
PCI_DEV_FLAGS_VPD_REF_F0 = (__force pci_dev_flags_t) (1 << 8),
|
||||||
/* a non-root bridge where translation occurs, stop alias search here */
|
/* a non-root bridge where translation occurs, stop alias search here */
|
||||||
PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT = (__force pci_dev_flags_t) (1 << 9),
|
PCI_DEV_FLAGS_BRIDGE_XLATE_ROOT = (__force pci_dev_flags_t) (1 << 9),
|
||||||
|
/* Do not use FLR even if device advertises PCI_AF_CAP */
|
||||||
|
PCI_DEV_FLAGS_NO_FLR_RESET = (__force pci_dev_flags_t) (1 << 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum pci_irq_reroute_variant {
|
enum pci_irq_reroute_variant {
|
||||||
|
@ -1037,6 +1039,7 @@ int pcie_get_mps(struct pci_dev *dev);
|
||||||
int pcie_set_mps(struct pci_dev *dev, int mps);
|
int pcie_set_mps(struct pci_dev *dev, int mps);
|
||||||
int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
|
int pcie_get_minimum_link(struct pci_dev *dev, enum pci_bus_speed *speed,
|
||||||
enum pcie_link_width *width);
|
enum pcie_link_width *width);
|
||||||
|
void pcie_flr(struct pci_dev *dev);
|
||||||
int __pci_reset_function(struct pci_dev *dev);
|
int __pci_reset_function(struct pci_dev *dev);
|
||||||
int __pci_reset_function_locked(struct pci_dev *dev);
|
int __pci_reset_function_locked(struct pci_dev *dev);
|
||||||
int pci_reset_function(struct pci_dev *dev);
|
int pci_reset_function(struct pci_dev *dev);
|
||||||
|
|
Loading…
Reference in New Issue