Page MenuHomeFreeBSD

D59498.id186178.diff
No OneTemporary

D59498.id186178.diff

diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -7013,6 +7013,34 @@
return (true);
}
+#define PCI_RESET_READY_TIMEOUT 1000 /* ms */
+
+/*
+ * Wait for a function to answer configuration requests after a reset; one
+ * that has not finished answers with all ones. May sleep.
+ */
+static bool
+pci_wait_for_ready(device_t dev, u_int max_delay)
+{
+
+ while (pci_read_config(dev, PCIR_VENDOR, 2) == PCIV_INVALID) {
+ if (max_delay == 0)
+ return (false);
+
+ /* Poll once every 10 milliseconds up to the timeout. */
+ if (max_delay > 10) {
+ pause_sbt("pcirdy", 10 * SBT_1MS, 0, C_HARDCLOCK);
+ max_delay -= 10;
+ } else {
+ pause_sbt("pcirdy", max_delay * SBT_1MS, 0,
+ C_HARDCLOCK);
+ max_delay = 0;
+ }
+ }
+
+ return (true);
+}
+
/*
* Determine the maximum Completion Timeout in microseconds.
*
@@ -7159,6 +7187,8 @@
* responsible for saving and restoring any registers including
* PCI-standard registers via pci_save_state() and
* pci_restore_state().
+ *
+ * On return the function is answering, or the failure was reported.
*/
bool
pcie_flr(device_t dev, u_int max_delay, bool force)
@@ -7210,6 +7240,13 @@
/* Wait for 100ms. */
pause_sbt("pcieflr", (100 + compl_delay) * SBT_1MS, 0, C_HARDCLOCK);
+ /* An unfinished reset reads back as a false pending. */
+ if (!pci_wait_for_ready(dev, PCI_RESET_READY_TIMEOUT)) {
+ pci_printf(&dinfo->cfg, "No response %d ms after FLR\n",
+ 100 + compl_delay + PCI_RESET_READY_TIMEOUT);
+ return (true);
+ }
+
if (pci_read_config(dev, cap + PCIER_DEVICE_STA, 2) &
PCIEM_STA_TRANSACTION_PND)
pci_printf(&dinfo->cfg, "Transactions pending after FLR!\n");
@@ -7224,6 +7261,7 @@
int
pci_power_reset(device_t dev)
{
+ struct pci_devinfo *dinfo = device_get_ivars(dev);
int ps;
ps = pci_get_powerstate(dev);
@@ -7231,6 +7269,11 @@
pci_set_powerstate(dev, PCI_POWERSTATE_D0);
pci_set_powerstate(dev, PCI_POWERSTATE_D3);
pci_set_powerstate(dev, ps);
+
+ /* Two D3 transitions, 10 ms each. */
+ if (!pci_wait_for_ready(dev, PCI_RESET_READY_TIMEOUT))
+ pci_printf(&dinfo->cfg, "No response %d ms after power reset\n",
+ 20 + PCI_RESET_READY_TIMEOUT);
return (0);
}

File Metadata

Mime Type
text/plain
Expires
Wed, Sep 9, 6:00 AM (12 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38538286
Default Alt Text
D59498.id186178.diff (2 KB)

Event Timeline