@@ -1043,7 +1043,7 @@ static int pci_dev_wait(struct pci_dev *dev, char *reset_type, int timeout)
if (delay > timeout) {
pci_warn(dev, "not ready %dms after %s; giving up\n",
delay - 1, reset_type);
- return -ENOTTY;
+ return -ETIMEDOUT;
}
if (delay > 1000)
@@ -4845,6 +4845,7 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
if (probe)
return 0;
+ /* XXX: Shouldn't this lock the bus? */
return pci_bridge_secondary_bus_reset(dev->bus->self);
}
@@ -4979,25 +4980,37 @@ int __pci_reset_function_locked(struct pci_dev *dev)
/*
* A reset method returns -ENOTTY if it doesn't support this device
* and we should try the next method.
+ * It returns -ETIMEDOUT if the device never became responsive after
+ * the reset: we jump to the reset types that do not rely on config
+ * space access (if any are left).
*
- * If it returns 0 (success), we're finished. If it returns any
- * other error, we're also finished: this indicates that further
- * reset mechanisms might be broken on the device.
+ * If it returns 0 (success), we are finished.
+ * If it returns any other error, we are finished (something must have
+ * went terribly wrong and it is not safe to continue reset attempts).
*/
rc = pci_dev_specific_reset(dev, 0);
+ if (rc == -ETIMEDOUT)
+ goto unresponsive;
if (rc != -ENOTTY)
return rc;
if (pcie_has_flr(dev)) {
rc = pcie_flr(dev);
+ if (rc == -ETIMEDOUT)
+ goto unresponsive;
if (rc != -ENOTTY)
return rc;
}
rc = pci_af_flr(dev, 0);
+ if (rc == -ETIMEDOUT)
+ goto unresponsive;
if (rc != -ENOTTY)
return rc;
rc = pci_pm_reset(dev, 0);
+ if (rc == -ETIMEDOUT)
+ goto unresponsive;
if (rc != -ENOTTY)
return rc;
+unresponsive:
rc = pci_dev_reset_slot_function(dev, 0);
if (rc != -ENOTTY)
return rc;