summaryrefslogtreecommitdiffstats
path: root/sys/dev/nvme/nvme_qpair.c
diff options
context:
space:
mode:
authorjimharris <jimharris@FreeBSD.org>2013-03-26 19:58:17 +0000
committerjimharris <jimharris@FreeBSD.org>2013-03-26 19:58:17 +0000
commit711dabaf432762eec4942b5f5f7611e7df825260 (patch)
tree94806202070a4ea8f80eaaf599bf2a85010d5097 /sys/dev/nvme/nvme_qpair.c
parentcef3145004715132223be663f7e0311b9ac7d779 (diff)
downloadFreeBSD-src-711dabaf432762eec4942b5f5f7611e7df825260.zip
FreeBSD-src-711dabaf432762eec4942b5f5f7611e7df825260.tar.gz
Add handling for controller fatal status (csts.cfs).
On any I/O timeout, check for csts.cfs==1. If set, the controller is reporting fatal status and we reset the controller immediately, rather than trying to abort the timed out command. This changeset also includes deferring the controller start portion of the reset to a separate task. This ensures we are always performing a controller start operation from a consistent context. Sponsored by: Intel Reviewed by: carl
Diffstat (limited to 'sys/dev/nvme/nvme_qpair.c')
-rw-r--r--sys/dev/nvme/nvme_qpair.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/sys/dev/nvme/nvme_qpair.c b/sys/dev/nvme/nvme_qpair.c
index f98125f..db9abf2 100644
--- a/sys/dev/nvme/nvme_qpair.c
+++ b/sys/dev/nvme/nvme_qpair.c
@@ -98,7 +98,7 @@ nvme_qpair_construct_tracker(struct nvme_qpair *qpair, struct nvme_tracker *tr,
bus_dmamap_load(qpair->dma_tag, tr->prp_dma_map, tr->prp,
sizeof(tr->prp), nvme_single_map, &tr->prp_bus_addr, 0);
- callout_init_mtx(&tr->timer, &qpair->lock, 0);
+ callout_init(&tr->timer, 1);
tr->cid = cid;
tr->qpair = qpair;
}
@@ -456,8 +456,24 @@ static void
nvme_timeout(void *arg)
{
struct nvme_tracker *tr = arg;
+ struct nvme_qpair *qpair = tr->qpair;
+ struct nvme_controller *ctrlr = qpair->ctrlr;
+ union csts_register csts;
- nvme_ctrlr_cmd_abort(tr->qpair->ctrlr, tr->cid, tr->qpair->id,
+ csts.raw = nvme_mmio_read_4(ctrlr, csts);
+ if (csts.bits.cfs == 1) {
+ /*
+ * The controller is reporting fatal status. Don't bother
+ * trying to abort the timed out command - proceed
+ * immediately to a controller-level reset.
+ */
+ device_printf(ctrlr->dev,
+ "controller reports fatal status, resetting...\n");
+ nvme_ctrlr_reset(ctrlr);
+ return;
+ }
+
+ nvme_ctrlr_cmd_abort(ctrlr, tr->cid, qpair->id,
nvme_abort_complete, tr);
}
OpenPOWER on IntegriCloud