aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2016-12-02 23:14:15 -0500
committerJens Axboe <axboe@fb.com>2016-12-13 23:07:08 -0500
commitd2a61918401ea8db8a6f922e98e86a66b4930cec (patch)
tree86146d83d19701e535012a589223db27329fee06
parentbcc7f5b4bee8e327689a4d994022765855c807ff (diff)
nvme/pci: Log PCI_STATUS when the controller dies
When debugging nvme controller crashes, it's nice to know whether the controller died cleanly so that the failure is just reflected in CSTS, it died and put an error in PCI_STATUS, or whether it died so badly that it stopped responding to PCI configuration space reads. I've seen a failure that gives 0xffff in PCI_STATUS on a Samsung "SM951 NVMe SAMSUNG 256GB" with firmware "BXW75D0Q". Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Keith Busch <keith.busch@intel.com> Fixed up white space and hunk reject. Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/nvme/host/pci.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index d6e6bce93d0c..2fd7dc2e8fc4 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1282,6 +1282,24 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
1282 return true; 1282 return true;
1283} 1283}
1284 1284
1285static void nvme_warn_reset(struct nvme_dev *dev, u32 csts)
1286{
1287 /* Read a config register to help see what died. */
1288 u16 pci_status;
1289 int result;
1290
1291 result = pci_read_config_word(to_pci_dev(dev->dev), PCI_STATUS,
1292 &pci_status);
1293 if (result == PCIBIOS_SUCCESSFUL)
1294 dev_warn(dev->dev,
1295 "controller is down; will reset: CSTS=0x%x, PCI_STATUS=0x%hx\n",
1296 csts, pci_status);
1297 else
1298 dev_warn(dev->dev,
1299 "controller is down; will reset: CSTS=0x%x, PCI_STATUS read failed (%d)\n",
1300 csts, result);
1301}
1302
1285static void nvme_watchdog_timer(unsigned long data) 1303static void nvme_watchdog_timer(unsigned long data)
1286{ 1304{
1287 struct nvme_dev *dev = (struct nvme_dev *)data; 1305 struct nvme_dev *dev = (struct nvme_dev *)data;
@@ -1290,9 +1308,7 @@ static void nvme_watchdog_timer(unsigned long data)
1290 /* Skip controllers under certain specific conditions. */ 1308 /* Skip controllers under certain specific conditions. */
1291 if (nvme_should_reset(dev, csts)) { 1309 if (nvme_should_reset(dev, csts)) {
1292 if (!nvme_reset(dev)) 1310 if (!nvme_reset(dev))
1293 dev_warn(dev->dev, 1311 nvme_warn_reset(dev, csts);
1294 "Failed status: 0x%x, reset controller.\n",
1295 csts);
1296 return; 1312 return;
1297 } 1313 }
1298 1314