aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/nvme
diff options
context:
space:
mode:
authorJim Harris <jimharris@FreeBSD.org>2015-07-23 15:50:39 +0000
committerJim Harris <jimharris@FreeBSD.org>2015-07-23 15:50:39 +0000
commitcbdec09c1c570740325dae25fcf12f0be99ed7b5 (patch)
tree5fe437c0359216c21d057883f056697a3abbb6ca /sys/dev/nvme
parentde9a58f4ee687d6e2fa055cecfee1328b0843219 (diff)
downloadsrc-cbdec09c1c570740325dae25fcf12f0be99ed7b5.tar.gz
src-cbdec09c1c570740325dae25fcf12f0be99ed7b5.zip
nvme: ensure csts.rdy bit is cleared before returning from nvme_ctrlr_disable
PR: 200458 MFC after: 3 days Sponsored by: Intel
Notes
Notes: svn path=/head/; revision=285816
Diffstat (limited to 'sys/dev/nvme')
-rw-r--r--sys/dev/nvme/nvme_ctrlr.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c
index bbcd6cc167ca..928d29445572 100644
--- a/sys/dev/nvme/nvme_ctrlr.c
+++ b/sys/dev/nvme/nvme_ctrlr.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (C) 2012-2014 Intel Corporation
+ * Copyright (C) 2012-2015 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -207,7 +207,7 @@ nvme_ctrlr_fail_req_task(void *arg, int pending)
}
static int
-nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr)
+nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr, int desired_val)
{
int ms_waited;
union cc_register cc;
@@ -216,18 +216,19 @@ nvme_ctrlr_wait_for_ready(struct nvme_controller *ctrlr)
cc.raw = nvme_mmio_read_4(ctrlr, cc);
csts.raw = nvme_mmio_read_4(ctrlr, csts);
- if (!cc.bits.en) {
- nvme_printf(ctrlr, "%s called with cc.en = 0\n", __func__);
+ if (cc.bits.en != desired_val) {
+ nvme_printf(ctrlr, "%s called with desired_val = %d "
+ "but cc.en = %d\n", __func__, desired_val, cc.bits.en);
return (ENXIO);
}
ms_waited = 0;
- while (!csts.bits.rdy) {
+ while (csts.bits.rdy != desired_val) {
DELAY(1000);
if (ms_waited++ > ctrlr->ready_timeout_in_ms) {
- nvme_printf(ctrlr, "controller did not become ready "
- "within %d ms\n", ctrlr->ready_timeout_in_ms);
+ nvme_printf(ctrlr, "controller ready did not become %d "
+ "within %d ms\n", desired_val, ctrlr->ready_timeout_in_ms);
return (ENXIO);
}
csts.raw = nvme_mmio_read_4(ctrlr, csts);
@@ -246,11 +247,12 @@ nvme_ctrlr_disable(struct nvme_controller *ctrlr)
csts.raw = nvme_mmio_read_4(ctrlr, csts);
if (cc.bits.en == 1 && csts.bits.rdy == 0)
- nvme_ctrlr_wait_for_ready(ctrlr);
+ nvme_ctrlr_wait_for_ready(ctrlr, 1);
cc.bits.en = 0;
nvme_mmio_write_4(ctrlr, cc, cc.raw);
DELAY(5000);
+ nvme_ctrlr_wait_for_ready(ctrlr, 0);
}
static int
@@ -267,7 +269,7 @@ nvme_ctrlr_enable(struct nvme_controller *ctrlr)
if (csts.bits.rdy == 1)
return (0);
else
- return (nvme_ctrlr_wait_for_ready(ctrlr));
+ return (nvme_ctrlr_wait_for_ready(ctrlr, 1));
}
nvme_mmio_write_8(ctrlr, asq, ctrlr->adminq.cmd_bus_addr);
@@ -295,7 +297,7 @@ nvme_ctrlr_enable(struct nvme_controller *ctrlr)
nvme_mmio_write_4(ctrlr, cc, cc.raw);
DELAY(5000);
- return (nvme_ctrlr_wait_for_ready(ctrlr));
+ return (nvme_ctrlr_wait_for_ready(ctrlr, 1));
}
int