PCI and PCIe devices may support a number of possible reset mechanisms
for example Function Level Reset (FLR) provided via Advanced Feature or
PCIe capabilities, Power Management reset, bus reset, or device specific reset.
Currently the PCI subsystem creates a policy prioritizing these reset methods
which provides neither visibility nor control to userspace.
Expose the reset methods available per device to userspace, via sysfs
and allow an administrative user or device owner to have ability to
manage per device reset method priorities or exclusions.
This feature aims to allow greater control of a device for use cases
as device assignment, where specific device or platform issues may
interact poorly with a given reset method, and for which device specific
quirks have not been developed.
Changes in v11:
- Alex's suggestion fallback back to other resets if the ACPI RST
fails. Fix "s/-EINVAL/-ENOTTY/" in 7/8 patch.
Changes in v10:
- Fix build error on ppc as reported by build bot
Changes in v9:
- Renamed has_flr bitfield to has_pcie_flr and restored
use of PCI_DEV_FLAGS_NO_FLR_RESET in quirk_no_flr()
- Cleaned up sysfs code
Changes in v8:
- Added has_flr bitfield to struct pci_dev to cache flr
capability
- Updated encoding scheme used in reset_methods array as per
Bjorn's suggestion
- Updated Shanker's ACPI patches
Changes in v7:
- Fix the pci_dev_acpi_reset() prototype mismatch
in case of CONFIG_ACPI=n
Changes in v6:
- Address Bjorn's and Krzysztof's review comments
- Add Shanker's updated patches along with new
"PCI: Setup ACPI_COMPANION early" patch
Changes in v5:
- Rebase the series over pci/reset branch of
Bjorn's pci tree to avoid merge conflicts
caused by recent changes in existing reset
sysfs attribute
Changes in v4:
- Change the order or strlen and strim in reset_method_store
function to avoid extra strlen call.
- Use consistent terminology in new
pci_reset_mode enum and rename the probe argument
of reset functions.
Changes in v3:
- Dropped "PCI: merge slot and bus reset implementations" which was
already accepted separately
- Grammar fixes
- Added Shanker's patches which were rebased on v2 of this series
- Added "PCI: Change the type of probe argument in reset functions"
and additional user input sanitization code in reset_method_store
function per review feedback from Krzysztof
Changes in v2:
- Use byte array instead of bitmap to keep track of
ordering of reset methods
- Fix incorrect use of reset_fn field in octeon driver
- Allow writing comma separated list of names of supported reset
methods to reset_method sysfs attribute
- Writing empty string instead of "none" to reset_method attribute
disables ability of reset the device
Amey Narkhede (5):
PCI: Add pcie_reset_flr to follow calling convention of other reset
methods
PCI: Add new array for keeping track of ordering of reset methods
PCI: Remove reset_fn field from pci_dev
PCI/sysfs: Allow userspace to query and set device reset mechanism
PCI: Change the type of probe argument in reset functions
Shanker Donthineni (3):
PCI: Define a function to set ACPI_COMPANION in pci_dev
PCI: Setup ACPI fwnode early and at the same time with OF
PCI: Add support for ACPI _RST reset method
Documentation/ABI/testing/sysfs-bus-pci | 19 ++
drivers/crypto/cavium/nitrox/nitrox_main.c | 4 +-
.../ethernet/cavium/liquidio/lio_vf_main.c | 2 +-
drivers/pci/hotplug/pciehp.h | 2 +-
drivers/pci/hotplug/pciehp_hpc.c | 4 +-
drivers/pci/hotplug/pnv_php.c | 4 +-
drivers/pci/pci-acpi.c | 38 +++-
drivers/pci/pci-sysfs.c | 107 ++++++++-
drivers/pci/pci.c | 215 ++++++++++--------
drivers/pci/pci.h | 23 +-
drivers/pci/pcie/aer.c | 12 +-
drivers/pci/probe.c | 17 +-
drivers/pci/quirks.c | 42 ++--
drivers/pci/remove.c | 1 -
include/linux/pci.h | 17 +-
include/linux/pci_hotplug.h | 2 +-
16 files changed, 363 insertions(+), 146 deletions(-)
--
2.25.1
The _RST is a standard method specified in the ACPI specification. It
provides a function level reset when it is described in the acpi_device
context associated with PCI-device. Implement a new reset function
pci_dev_acpi_reset() for probing RST method and execute if it is defined
in the firmware.
The default priority of the ACPI reset is set to below device-specific
and above hardware resets.
Signed-off-by: Shanker Donthineni <[email protected]>
Suggested-by: Alex Williamson <[email protected]>
Reviewed-by: Sinan Kaya <[email protected]>
Reviewed-by: Alex Williamson <[email protected]>
---
drivers/pci/pci-acpi.c | 23 +++++++++++++++++++++++
drivers/pci/pci.c | 1 +
drivers/pci/pci.h | 6 ++++++
include/linux/pci.h | 2 +-
4 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index dae021322b3fc..31f76746741f5 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -941,6 +941,29 @@ void pci_set_acpi_fwnode(struct pci_dev *dev)
acpi_pci_find_companion(&dev->dev));
}
+/**
+ * pci_dev_acpi_reset - do a function level reset using _RST method
+ * @dev: device to reset
+ * @probe: check if _RST method is included in the acpi_device context.
+ */
+int pci_dev_acpi_reset(struct pci_dev *dev, int probe)
+{
+ acpi_handle handle = ACPI_HANDLE(&dev->dev);
+
+ if (!handle || !acpi_has_method(handle, "_RST"))
+ return -ENOTTY;
+
+ if (probe)
+ return 0;
+
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_RST", NULL, NULL))) {
+ pci_warn(dev, "ACPI _RST failed\n");
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
static bool acpi_pci_bridge_d3(struct pci_dev *dev)
{
const struct fwnode_handle *fwnode;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index cc9f96effa546..8aab4097f80bc 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -5127,6 +5127,7 @@ static void pci_dev_restore(struct pci_dev *dev)
const struct pci_reset_fn_method pci_reset_fn_methods[] = {
{ },
{ &pci_dev_specific_reset, .name = "device_specific" },
+ { &pci_dev_acpi_reset, .name = "acpi" },
{ &pcie_reset_flr, .name = "flr" },
{ &pci_af_flr, .name = "af_flr" },
{ &pci_pm_reset, .name = "pm" },
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 37381734fcc78..699d14243867a 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -709,7 +709,13 @@ static inline int pci_aer_raw_clear_status(struct pci_dev *dev) { return -EINVAL
int pci_acpi_program_hp_params(struct pci_dev *dev);
extern const struct attribute_group pci_dev_acpi_attr_group;
void pci_set_acpi_fwnode(struct pci_dev *dev);
+int pci_dev_acpi_reset(struct pci_dev *dev, int probe);
#else
+static inline int pci_dev_acpi_reset(struct pci_dev *dev, int probe)
+{
+ return -ENOTTY;
+}
+
static inline void pci_set_acpi_fwnode(struct pci_dev *dev) {}
static inline int pci_acpi_program_hp_params(struct pci_dev *dev)
{
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 58cc2e2b05051..698a668828f66 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -50,7 +50,7 @@
PCI_STATUS_PARITY)
/* Number of reset methods used in pci_reset_fn_methods array in pci.c */
-#define PCI_NUM_RESET_METHODS 6
+#define PCI_NUM_RESET_METHODS 7
/*
* The PCI interface treats multi-function devices as independent
--
2.25.1
Hi Bjorn/Alex,
I've posted v11 with the incorrect subject in 0/8, please use v12 patch series for review.
Thanks,
Shanker Donthineni