Skip to content

Commit 5b2c214

Browse files
keithbuschChristoph Hellwig
authored andcommitted
nvme-pci: try function level reset on init failure
NVMe devices from multiple vendors appear to get stuck in a reset state that we can't get out of with an NVMe level Controller Reset. The kernel would report these with messages that look like: Device not ready; aborting reset, CSTS=0x1 These have historically required a power cycle to make them usable again, but in many cases, a PCIe FLR is sufficient to restart operation without a power cycle. Try it if the initial controller reset fails during any nvme reset attempt. Signed-off-by: Keith Busch <[email protected]> Reviewed-by: Chaitanya Kulkarni <[email protected]> Reviewed-by: Nitesh Shetty <[email protected]> Signed-off-by: Christoph Hellwig <[email protected]>
1 parent 746d0ac commit 5b2c214

1 file changed

Lines changed: 22 additions & 2 deletions

File tree

drivers/nvme/host/pci.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2064,8 +2064,28 @@ static int nvme_pci_configure_admin_queue(struct nvme_dev *dev)
20642064
* might be pointing at!
20652065
*/
20662066
result = nvme_disable_ctrl(&dev->ctrl, false);
2067-
if (result < 0)
2068-
return result;
2067+
if (result < 0) {
2068+
struct pci_dev *pdev = to_pci_dev(dev->dev);
2069+
2070+
/*
2071+
* The NVMe Controller Reset method did not get an expected
2072+
* CSTS.RDY transition, so something with the device appears to
2073+
* be stuck. Use the lower level and bigger hammer PCIe
2074+
* Function Level Reset to attempt restoring the device to its
2075+
* initial state, and try again.
2076+
*/
2077+
result = pcie_reset_flr(pdev, false);
2078+
if (result < 0)
2079+
return result;
2080+
2081+
pci_restore_state(pdev);
2082+
result = nvme_disable_ctrl(&dev->ctrl, false);
2083+
if (result < 0)
2084+
return result;
2085+
2086+
dev_info(dev->ctrl.device,
2087+
"controller reset completed after pcie flr\n");
2088+
}
20692089

20702090
result = nvme_alloc_queue(dev, 0, NVME_AQ_DEPTH);
20712091
if (result)

0 commit comments

Comments
 (0)