PCI: Ignore Immediate Readiness on Samsung 990 PRO and 990 EVO Plus NVMe

The Samsung 990 PRO [144d:a80c] advertises Immediate Readiness, so
pcie_flr() doesn't wait after FLR, but the drive returns ~0 for up to 7 ms.
Since commit 10baa9b4df ("PCI: Drop unnecessary retries when restoring
BARs"), the config restore after FLR is lost, which breaks VFIO passthrough
of the drive.  Firmware 8B2QJXD7 responds right after FLR, but older
firmware such as 1B2QJXD7 doesn't, and the firmware version isn't visible
here.

[bhelgaas: The Samsung 990 EVO Plus [144d:a80d] with 2B2QKXG7 firmware
seems to have the same problem.]

Ignore Immediate Readiness on these devices, so pcie_flr() waits.

Fixes: 10baa9b4df ("PCI: Drop unnecessary retries when restoring BARs")
Link: https://bbs.archlinux.org/viewtopic.php?id=314833
Link: https://bbs.archlinux.org/viewtopic.php?pid=2312085#p2312085
Suggested-by: Lukas Wunner <[email protected]>
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Alexander Gruhlke <[email protected]>
[bhelgaas: squashed in Samsung 990 EVO Plus from
https://lore.kernel.org/all/[email protected]]
Signed-off-by: Bjorn Helgaas <[email protected]>
Reviewed-by: Lukas Wunner <[email protected]>
Link: https://patch.msgid.link/[email protected]
Link: https://patch.msgid.link/[email protected]
This commit is contained in:
Alexander Gruhlke authored and Bjorn Helgaas committed 2026-10-16 12:05:18 -05:00
1 parent cee9395acd
commit 0f8b5d90d1
1 file changed
+12
+12
View File
@@ -5623,6 +5623,18 @@ static void quirk_no_flr_snet(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_SOLIDRUN, 0x1000, quirk_no_flr_snet);
/* Some Samsung SSDs advertise Immediate Readiness but aren't ready after FLR */
static void quirk_no_imm_ready(struct pci_dev *dev)
{
if (!dev->imm_ready)
return;
pci_info(dev, "Ignoring incorrectly advertised Immediate Readiness support\n");
dev->imm_ready = 0;
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SAMSUNG, 0xa80c, quirk_no_imm_ready);
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SAMSUNG, 0xa80d, quirk_no_imm_ready);
static void quirk_no_ext_tags(struct pci_dev *pdev)
{
struct pci_host_bridge *bridge = pci_find_host_bridge(pdev->bus);