diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -583,14 +583,16 @@ } static int -nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr) +nvme_ctrlr_construct_namespaces(struct nvme_controller *ctrlr, bool resetting) { struct nvme_namespace *ns; uint32_t i; for (i = 0; i < min(ctrlr->cdata.nn, NVME_MAX_NAMESPACES); i++) { ns = &ctrlr->ns[i]; - nvme_ns_construct(ns, i+1, ctrlr); + if (!resetting) + nvme_ns_init(ns, i+1, ctrlr); + nvme_ns_construct(ns); } return (0); @@ -1154,7 +1156,7 @@ return; } - if (nvme_ctrlr_construct_namespaces(ctrlr) != 0) { + if (nvme_ctrlr_construct_namespaces(ctrlr, resetting) != 0) { nvme_ctrlr_fail(ctrlr, false); return; } diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c --- a/sys/dev/nvme/nvme_ns.c +++ b/sys/dev/nvme/nvme_ns.c @@ -516,10 +516,19 @@ return (nvme_ns_ioctl(ns->cdev, cmd, arg, flag, td)); } -int -nvme_ns_construct(struct nvme_namespace *ns, uint32_t id, +void +nvme_ns_init(struct nvme_namespace *ns, uint32_t id, struct nvme_controller *ctrlr) { + ns->ctrlr = ctrlr; + ns->id = id; + mtx_init(&ns->lock, "nvme ns lock", NULL, MTX_DEF); +} + +int +nvme_ns_construct(struct nvme_namespace *ns) +{ + struct nvme_controller *ctrlr = ns->ctrlr; struct make_dev_args md_args; struct nvme_completion_poll_status status; int res; @@ -527,22 +536,8 @@ uint8_t flbas_fmt; uint8_t vwc_present; - ns->ctrlr = ctrlr; - ns->id = id; - - /* - * Namespaces are reconstructed after a controller reset, so check - * to make sure we only call mtx_init once on each mtx. - * - * TODO: Move this somewhere where it gets called at controller - * construction time, which is not invoked as part of each - * controller reset. - */ - if (!mtx_initialized(&ns->lock)) - mtx_init(&ns->lock, "nvme ns lock", NULL, MTX_DEF); - status.done = 0; - nvme_ctrlr_cmd_identify_namespace(ctrlr, id, &ns->data, + nvme_ctrlr_cmd_identify_namespace(ctrlr, ns->id, &ns->data, nvme_completion_poll_cb, &status); nvme_completion_poll(&status); if (nvme_completion_is_error(&status.cpl)) { @@ -569,7 +564,7 @@ flbas_fmt = NVMEV(NVME_NS_DATA_FLBAS_FORMAT, ns->data.flbas); if (flbas_fmt > ns->data.nlbaf) { nvme_printf(ctrlr, "nsid %d lba format %d invalid (> %d)\n", - id, flbas_fmt, ns->data.nlbaf + 1); + ns->id, flbas_fmt, ns->data.nlbaf + 1); return (ENXIO); } diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -425,8 +425,9 @@ void nvme_io_qpair_disable(struct nvme_qpair *qpair); void nvme_io_qpair_destroy(struct nvme_qpair *qpair); -int nvme_ns_construct(struct nvme_namespace *ns, uint32_t id, - struct nvme_controller *ctrlr); +void nvme_ns_init(struct nvme_namespace *ns, uint32_t id, + struct nvme_controller *ctrlr); +int nvme_ns_construct(struct nvme_namespace *ns); void nvme_ns_destruct(struct nvme_namespace *ns); void nvme_sysctl_initialize_ctrlr(struct nvme_controller *ctrlr);