summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/common/io/nvme/nvme.c44
-rw-r--r--usr/src/uts/common/io/nvme/nvme_var.h2
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 {