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);
 	}