nvme: split off __nvme_init_subsystem()
Split of __nvme_init_subsystem() to separate out initialisation
from registration of the subsystem.
Signed-off-by: Hannes Reinecke <hare@suse.de>
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 4bdc30d..1de3f42 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2869,28 +2869,25 @@ static bool nvme_validate_cntlid(struct nvme_subsystem *subsys,
return true;
}
-static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+static struct nvme_subsystem *__nvme_init_subsystem(struct nvme_id_ctrl *id)
{
- struct nvme_subsystem *subsys, *found;
+ struct nvme_subsystem *subsys;
int ret;
subsys = kzalloc(sizeof(*subsys), GFP_KERNEL);
if (!subsys)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
ret = ida_alloc(&nvme_subsystem_ida, GFP_KERNEL);
if (ret < 0) {
kfree(subsys);
- return ret;
+ return ERR_PTR(ret);
}
subsys->instance = ret;
mutex_init(&subsys->lock);
kref_init(&subsys->ref);
INIT_LIST_HEAD(&subsys->ctrls);
INIT_LIST_HEAD(&subsys->nsheads);
- if (!strnlen(id->subnqn, NVMF_NQN_SIZE) &&
- ctrl->vs >= NVME_VS(1,2,1))
- dev_warn(ctrl->device, "missing or invalid SUBNQN field.\n");
memcpy(subsys->subnqn, id->subnqn, NVMF_NQN_SIZE);
memcpy(subsys->serial, id->sn, sizeof(subsys->serial));
memcpy(subsys->model, id->mn, sizeof(subsys->model));
@@ -2905,6 +2902,31 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
else
subsys->subtype = NVME_NQN_NVME;
+ nvme_mpath_default_iopolicy(subsys);
+
+ subsys->dev.class = nvme_subsys_class;
+ subsys->dev.release = nvme_release_subsystem;
+ subsys->dev.groups = nvme_subsys_attrs_groups;
+ dev_set_name(&subsys->dev, "nvme-subsys%d", subsys->instance);
+ device_initialize(&subsys->dev);
+ ida_init(&subsys->ns_ida);
+
+ return subsys;
+}
+
+static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+{
+ struct nvme_subsystem *subsys, *found;
+ int ret;
+
+ subsys = __nvme_init_subsystem(id);
+ if (IS_ERR(subsys))
+ return PTR_ERR(subsys);
+
+ if (!strnlen(id->subnqn, NVMF_NQN_SIZE) &&
+ ctrl->vs >= NVME_VS(1,2,1))
+ dev_warn(ctrl->device, "missing or invalid SUBNQN field.\n");
+
if (nvme_discovery_ctrl(ctrl) && subsys->subtype != NVME_NQN_DISC) {
dev_err(ctrl->device,
"Subsystem %s is not a discovery controller",
@@ -2913,13 +2935,6 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
kfree(subsys);
return -EINVAL;
}
- nvme_mpath_default_iopolicy(subsys);
-
- subsys->dev.class = nvme_subsys_class;
- subsys->dev.release = nvme_release_subsystem;
- subsys->dev.groups = nvme_subsys_attrs_groups;
- dev_set_name(&subsys->dev, "nvme-subsys%d", subsys->instance);
- device_initialize(&subsys->dev);
mutex_lock(&nvme_subsystems_lock);
found = __nvme_find_get_subsystem(subsys->subnqn);
@@ -2939,7 +2954,6 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
put_device(&subsys->dev);
goto out_unlock;
}
- ida_init(&subsys->ns_ida);
list_add_tail(&subsys->entry, &nvme_subsystems);
}