Code polling NVME_CSTS_SHST_CMPLT in nvme_shutdown_ctrl() is very similar to polling loop in nvme_wait_ready(). Move shared polling loop code into __nvme_wait_ready() and re-implement both nvme_shutdown_ctrl() and nvme_wait_ready() on top of it to avoid code repetition.
Signed-off-by: Andrey Smirnov <andrew.smir...@gmail.com> Cc: Keith Busch <keith.bu...@intel.com> Cc: Jens Axboe <ax...@fb.com> Cc: Christoph Hellwig <h...@lst.de> Cc: Sagi Grimberg <s...@grimberg.me> Cc: linux-n...@lists.infradead.org Cc: linux-kernel@vger.kernel.org --- drivers/nvme/host/core.c | 54 ++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index b47c59f0cbd8..633fbc21425c 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1797,28 +1797,41 @@ const struct block_device_operations nvme_ns_head_ops = { }; #endif /* CONFIG_NVME_MULTIPATH */ -static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled) +static int __nvme_wait_ready(struct nvme_ctrl *ctrl, u32 mask, u32 value, + unsigned long timeout) { - unsigned long timeout = - ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies; - u32 csts, bit = enabled ? NVME_CSTS_RDY : 0; + u32 csts; int ret; while ((ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &csts)) == 0) { if (csts == ~0) return -ENODEV; - if ((csts & NVME_CSTS_RDY) == bit) + if ((csts & mask) == value) break; msleep(100); if (fatal_signal_pending(current)) return -EINTR; - if (time_after(jiffies, timeout)) { - dev_err(ctrl->device, - "Device not ready; aborting %s\n", enabled ? - "initialisation" : "reset"); - return -ENODEV; - } + if (time_after(jiffies, timeout)) + return -ETIMEDOUT; + } + + return ret; +} + +static int nvme_wait_ready(struct nvme_ctrl *ctrl, u64 cap, bool enabled) +{ + unsigned long timeout = + ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies; + u32 bit = enabled ? NVME_CSTS_RDY : 0; + int ret; + + ret = __nvme_wait_ready(ctrl, NVME_CSTS_RDY, bit, timeout); + if (ret == -ETIMEDOUT) { + dev_err(ctrl->device, + "Device not ready; aborting %s\n", enabled ? + "initialisation" : "reset"); + ret = -ENODEV; } return ret; @@ -1883,7 +1896,6 @@ EXPORT_SYMBOL_GPL(nvme_enable_ctrl); int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl) { unsigned long timeout = jiffies + (ctrl->shutdown_timeout * HZ); - u32 csts; int ret; ctrl->ctrl_config &= ~NVME_CC_SHN_MASK; @@ -1893,18 +1905,12 @@ int nvme_shutdown_ctrl(struct nvme_ctrl *ctrl) if (ret) return ret; - while ((ret = ctrl->ops->reg_read32(ctrl, NVME_REG_CSTS, &csts)) == 0) { - if ((csts & NVME_CSTS_SHST_MASK) == NVME_CSTS_SHST_CMPLT) - break; - - msleep(100); - if (fatal_signal_pending(current)) - return -EINTR; - if (time_after(jiffies, timeout)) { - dev_err(ctrl->device, - "Device shutdown incomplete; abort shutdown\n"); - return -ENODEV; - } + ret = __nvme_wait_ready(ctrl, NVME_CSTS_SHST_MASK, + NVME_CSTS_SHST_CMPLT, timeout); + if (ret == -ETIMEDOUT) { + dev_err(ctrl->device, + "Device shutdown incomplete; abort shutdown\n"); + ret = -ENODEV; } return ret; -- 2.20.1