@@ -1081,18 +1081,54 @@ static int pci_dev_wait(struct pci_dev *dev, enum pci_init_event event)
{
const char *event_name = pci_init_event_name(event);
int timeout = dev->reset_ready_poll_ms;
+ int waited = 0;
+ int rc = 0;
+
/*
* After reset, the device should not silently discard config
* requests, but it may still indicate that it needs more time by
- * responding to them with CRS completions. The Root Port will
- * generally synthesize ~0 data to complete the read (except when
- * CRS SV is enabled and the read was for the Vendor ID; in that
- * case it synthesizes 0x0001 data).
- *
- * Wait for the device to return a non-CRS completion. Read the
- * Command register instead of Vendor ID so we don't have to
- * contend with the CRS SV value.
+ * responding to them with CRS completions. For such completions:
+ * - If CRS SV is enabled on the Root Port, and the read request
+ * covers both bytes of the Vendor ID register, the Root Port
+ * will synthesize the value 0x0001 (and set any extra requested
+ * bytes to 0xff)
+ * - If CRS SV is not enabled on the Root Port, the Root Port must
+ * re-issue the Configuration Request as a new Request.
+ * Depending on platform-specific Root Complex configurations,
+ * the Root Port may stop retrying after a set number of attempts,
+ * or a configured timeout is hit, or continue indefinitely
+ * (ultimately resulting in non-PCI-specific platform errors, such as
+ * a TOR timeout).
+ */
+ if (dev->crssv_enabled) {
+ u32 id;
+
+ rc = pci_dev_poll_until_not_equal(dev, PCI_VENDOR_ID, 0xffff,
+ 0x0001, event_name, timeout,
+ &waited, &id);
+ if (rc)
+ return rc;
+
+ /*
+ * If Vendor/Device ID is valid, the device must be ready.
+ * Note: SR-IOV VFs return ~0 for reads to Vendor/Device
+ * ID and will not be recognized as ready by this check.
+ */
+ if (id != 0x0000ffff && id != 0xffff0000 &&
+ id != 0x00000000 && id != 0xffffffff)
+ return 0;
+ }
+
+ /*
+ * Root Ports will generally indicate error scenarios (e.g.
+ * internal timeouts, or received Completion with CA/UR) by
+ * synthesizing an 'all bits set' value (~0).
+ * In case CRS is not supported/enabled, as well as for SR-IOV VFs,
+ * fall back to polling a different register that cannot validly
+ * contain ~0. As of PCIe 5.0, bits 11-15 of COMMAND are still RsvdP
+ * and must return 0 when read.
+ * XXX: These bits might become meaningful in the future
*/
return pci_dev_poll_until_not_equal(dev, PCI_COMMAND, ~0, ~0,
event_name, timeout, NULL,