git: 5b48968c1a57 - main - pci: Export pcie_flr_supported()

Kevin Bowling <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a80fe15.3207e.62b58d4c__34337.6853082859$1786838563$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by kbowling:

URL: https://cgit.FreeBSD.org/src/commit/?id=5b48968c1a57bd1a7f086d7e09add59afa158340

commit 5b48968c1a57bd1a7f086d7e09add59afa158340
Author:     Kevin Bowling <[email protected]>
AuthorDate: 2026-08-15 23:47:10 +0000
Commit:     Kevin Bowling <[email protected]>
CommitDate: 2026-08-16 00:01:35 +0000

    pci: Export pcie_flr_supported()
    
    Move the capability and quirk checks used by pcie_flr() into a public
    side effect free helper.  This lets callers determine whether an FLR
    can be attempted before quiescing a device or saving state.
    
    The helper considers the advertised PCIe FLR capability and both the
    enable and disable FLR quirks.
    
    MFC after:      2 weeks
    Sponsored by:   BBOX.io
---
 share/man/man9/pci.9 | 15 ++++++++++++++-
 sys/dev/pci/pci.c    | 31 ++++++++++++++++++++++++-------
 sys/dev/pci/pcivar.h |  1 +
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/share/man/man9/pci.9 b/share/man/man9/pci.9
index c94982f5f218..65d1f0bc867b 100644
--- a/share/man/man9/pci.9
+++ b/share/man/man9/pci.9
@@ -23,7 +23,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd August 6, 2026
+.Dd August 15, 2026
 .Dt PCI 9
 .Os
 .Sh NAME
@@ -72,6 +72,7 @@
 .Nm pci_write_config ,
 .Nm pcie_adjust_config ,
 .Nm pcie_flr ,
+.Nm pcie_flr_supported ,
 .Nm pcie_get_max_completion_timeout ,
 .Nm pcie_read_config ,
 .Nm pcie_wait_for_pending_transactions ,
@@ -169,6 +170,8 @@
 .Fc
 .Ft bool
 .Fn pcie_flr "device_t dev" "u_int max_delay" "bool force"
+.Ft bool
+.Fn pcie_flr_supported "device_t dev"
 .Ft int
 .Fn pcie_get_max_completion_timeout "device_t dev"
 .Ft uint32_t
@@ -863,6 +866,16 @@ Note that
 .Nm pcie_flr
 does not save and restore any state around the reset.
 The caller should save and restore state as needed.
+.Pp
+The
+.Fn pcie_flr_supported
+function returns
+.Dv true
+if
+.Fa dev
+supports FLR according to its PCI-express capability and the PCI quirk
+policy.
+It does not alter the device.
 .Ss Message Signaled Interrupts
 Message Signaled Interrupts
 .Pq MSI
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 34ee261604a2..430eca38c0b9 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -7078,6 +7078,28 @@ pcie_apei_error(device_t dev, int sev, uint8_t *aerp)
 	}
 }
 
+/*
+ * Return true if the device supports FLR, taking both its advertised
+ * capability and the PCI quirk policy into account.
+ */
+bool
+pcie_flr_supported(device_t dev)
+{
+	struct pci_devinfo *dinfo = device_get_ivars(dev);
+	int cap;
+
+	cap = dinfo->cfg.pcie.pcie_location;
+	if (cap == 0)
+		return (false);
+
+	if (!(pci_read_config(dev, cap + PCIER_DEVICE_CAP, 4) & PCIEM_CAP_FLR) &&
+	    !pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_ENABLE_FLR))
+		return (false);
+	if (pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_DISABLE_FLR))
+		return (false);
+	return (true);
+}
+
 /*
  * Perform a Function Level Reset (FLR) on a device.
  *
@@ -7102,15 +7124,10 @@ pcie_flr(device_t dev, u_int max_delay, bool force)
 	int compl_delay;
 	int cap;
 
-	cap = dinfo->cfg.pcie.pcie_location;
-	if (cap == 0)
+	if (!pcie_flr_supported(dev))
 		return (false);
 
-	if (!(pci_read_config(dev, cap + PCIER_DEVICE_CAP, 4) & PCIEM_CAP_FLR) &&
-	    !pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_ENABLE_FLR))
-		return (false);
-	if (pci_has_quirk(pci_get_devid(dev), PCI_QUIRK_DISABLE_FLR))
-		return (false);
+	cap = dinfo->cfg.pcie.pcie_location;
 
 	/*
 	 * Disable busmastering to prevent generation of new
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index 27bac22c7896..19ba20a7d1f3 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -711,6 +711,7 @@ uint32_t pcie_adjust_config(device_t dev, int reg, uint32_t mask,
 	    uint32_t value, int width);
 void	pcie_apei_error(device_t dev, int sev, uint8_t *aer);
 bool	pcie_flr(device_t dev, u_int max_delay, bool force);
+bool	pcie_flr_supported(device_t dev);
 int	pcie_get_max_completion_timeout(device_t dev);
 bool	pcie_wait_for_pending_transactions(device_t dev, u_int max_delay);
 int	pcie_link_reset(device_t port, int pcie_location);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.