[SRU][unstabe/Q/P][PATCH 1/1] UBUNTU: SAUCE: PCI: Disable RRS polling for Intel SSDPE2KX020T8 nvme
Hui Wang
hui.wang at canonical.com
Tue Aug 19 08:21:23 UTC 2025
BugLink: https://bugs.launchpad.net/bugs/2111521
Prior to commit d591f6804e7e ("PCI: Wait for device readiness with
Configuration RRS"), this Intel nvme [8086:0a54] works well. Since
that patch is merged to the kernel, this nvme stops working.
Through debugging, we found that commit introduces the RRS polling in
the pci_dev_wait(), for this nvme, when polling the PCI_VENDOR_ID, it
will return ~0 if the config access is not ready yet, but the polling
expects a return value of 0x0001 or a valid vendor_id, so the RRS
polling doesn't work for this nvme.
Here we add a pci quirk to disable the RRS polling for the device.
Fixes: d591f6804e7e ("PCI: Wait for device readiness with Configuration RRS")
Signed-off-by: Hui Wang <hui.wang at canonical.com>
---
drivers/pci/probe.c | 3 ++-
drivers/pci/quirks.c | 18 ++++++++++++++++++
include/linux/pci.h | 2 ++
3 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 3da48c13d9cc..2d1bebc1c159 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1265,7 +1265,8 @@ static void pci_enable_rrs_sv(struct pci_dev *pdev)
if (root_cap & PCI_EXP_RTCAP_RRS_SV) {
pcie_capability_set_word(pdev, PCI_EXP_RTCTL,
PCI_EXP_RTCTL_RRS_SVE);
- pdev->config_rrs_sv = 1;
+ if (!(pdev->dev_flags & PCI_DEV_FLAGS_NO_RRS_SV))
+ pdev->config_rrs_sv = 1;
}
}
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 0d51c5d378da..530d669f92ec 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -6331,3 +6331,21 @@ static void pci_mask_replay_timer_timeout(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9750, pci_mask_replay_timer_timeout);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_GLI, 0x9755, pci_mask_replay_timer_timeout);
#endif
+
+/*
+ * Although the root port device claims to support RRS, some devices don't work
+ * with RRS polling, when reading the Vendor ID, they just return ~0 if config
+ * access is not ready, this will break the pci_dev_wait(). Here disable the RRS
+ * forcibly for this type of device.
+ */
+static void quirk_no_rrs_sv(struct pci_dev *dev)
+{
+ struct pci_dev *root;
+
+ root = pcie_find_root_port(dev);
+ if (root) {
+ root->dev_flags |= PCI_DEV_FLAGS_NO_RRS_SV;
+ root->config_rrs_sv = 0;
+ }
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x0a54, quirk_no_rrs_sv);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 255097538e19..7adb115bb419 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -247,6 +247,8 @@ enum pci_dev_flags {
PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12),
/* Device requires write to PCI_MSIX_ENTRY_DATA before any MSIX reads */
PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST = (__force pci_dev_flags_t) (1 << 13),
+ /* Do not use Configuration Request Retry Status polling in pci_dev_wait() */
+ PCI_DEV_FLAGS_NO_RRS_SV = (__force pci_dev_flags_t) (1 << 14),
};
enum pci_irq_reroute_variant {
--
2.34.1
More information about the kernel-team
mailing list