diff options
-rw-r--r-- | usr/src/uts/common/io/nvme/nvme.c | 44 | ||||
-rw-r--r-- | usr/src/uts/common/io/nvme/nvme_var.h | 2 |
2 files changed, 38 insertions, 8 deletions
diff --git a/usr/src/uts/common/io/nvme/nvme.c b/usr/src/uts/common/io/nvme/nvme.c index a59564544f..00ed176144 100644 --- a/usr/src/uts/common/io/nvme/nvme.c +++ b/usr/src/uts/common/io/nvme/nvme.c @@ -3817,6 +3817,27 @@ nvme_remove_callback(dev_info_t *dip, ddi_eventcookie_t cookie, void *a, } } +static void +nvme_attach_children(void *arg) +{ + nvme_t *nvme = arg; + int i; + + mutex_enter(&nvme->n_mgmt_mutex); + + for (i = 1; i <= nvme->n_namespace_count; i++) { + int rv; + + rv = nvme_attach_ns(nvme, i); + if (rv != 0 && rv != ENOTSUP) { + dev_err(nvme->n_dip, CE_WARN, + "!failed to attach namespace %d: %d", i, rv); + } + } + + mutex_exit(&nvme->n_mgmt_mutex); +} + static int nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { @@ -4003,13 +4024,12 @@ nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) nvme->n_progress |= NVME_MGMT_INIT; /* - * Identify and attach namespaces. + * Identify namespaces. */ mutex_enter(&nvme->n_mgmt_mutex); for (i = 1; i <= nvme->n_namespace_count; i++) { nvme_namespace_t *ns = NVME_NSID2NS(nvme, i); - int rv; /* * Namespaces start out ignored. When nvme_init_ns() checks @@ -4023,12 +4043,6 @@ nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) goto fail; } - rv = nvme_attach_ns(nvme, i); - if (rv != 0 && rv != ENOTSUP) { - mutex_exit(&nvme->n_mgmt_mutex); - goto fail; - } - if (ddi_create_minor_node(nvme->n_dip, ns->ns_name, S_IFCHR, NVME_MINOR(ddi_get_instance(nvme->n_dip), i), DDI_NT_NVME_ATTACHMENT_POINT, 0) != DDI_SUCCESS) { @@ -4049,6 +4063,17 @@ nvme_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) goto fail; } + nvme->n_tq = ddi_taskq_create(dip, "attach_children", 1, + TASKQ_DEFAULTPRI, 0); + if (nvme->n_tq == NULL) { + dev_err(dip, CE_WARN, + "!failed to create attach_children taskq"); + goto fail; + } + + (void) ddi_taskq_dispatch(nvme->n_tq, nvme_attach_children, nvme, + DDI_SLEEP); + return (DDI_SUCCESS); fail: @@ -4077,6 +4102,9 @@ nvme_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) if (nvme == NULL) return (DDI_FAILURE); + if (nvme->n_tq != NULL) + ddi_taskq_destroy(nvme->n_tq); + ddi_remove_minor_node(dip, "devctl"); if (nvme->n_ns) { diff --git a/usr/src/uts/common/io/nvme/nvme_var.h b/usr/src/uts/common/io/nvme/nvme_var.h index 10cc529fd9..4d06e618f8 100644 --- a/usr/src/uts/common/io/nvme/nvme_var.h +++ b/usr/src/uts/common/io/nvme/nvme_var.h @@ -273,6 +273,8 @@ struct nvme { nvme_fwslot_log_t *n_fwslot; /* Lock protecting the cached firmware slot info */ kmutex_t n_fwslot_mutex; + + ddi_taskq_t *n_tq; }; struct nvme_namespace { |