hw/nvme: always initialize a subsystem

If no nvme-subsys is explicitly configured, instantiate one.

Reviewed-by: Jesper Wendel Devantier <foss@defmacro.it>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
Klaus Jensen 2024-12-16 13:53:02 +01:00
parent 23a4b3ebc7
commit cd59f50ab0
2 changed files with 42 additions and 58 deletions

View file

@ -8823,7 +8823,6 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
id->psd[0].enlat = cpu_to_le32(0x10); id->psd[0].enlat = cpu_to_le32(0x10);
id->psd[0].exlat = cpu_to_le32(0x4); id->psd[0].exlat = cpu_to_le32(0x4);
if (n->subsys) {
id->cmic |= NVME_CMIC_MULTI_CTRL; id->cmic |= NVME_CMIC_MULTI_CTRL;
ctratt |= NVME_CTRATT_ENDGRPS; ctratt |= NVME_CTRATT_ENDGRPS;
@ -8832,7 +8831,6 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
if (n->subsys->endgrp.fdp.enabled) { if (n->subsys->endgrp.fdp.enabled) {
ctratt |= NVME_CTRATT_FDPS; ctratt |= NVME_CTRATT_FDPS;
} }
}
id->ctratt = cpu_to_le32(ctratt); id->ctratt = cpu_to_le32(ctratt);
@ -8860,7 +8858,15 @@ static int nvme_init_subsys(NvmeCtrl *n, Error **errp)
int cntlid; int cntlid;
if (!n->subsys) { if (!n->subsys) {
return 0; DeviceState *dev = qdev_new(TYPE_NVME_SUBSYS);
qdev_prop_set_string(dev, "nqn", n->params.serial);
if (!qdev_realize(dev, NULL, errp)) {
return -1;
}
n->subsys = NVME_SUBSYS(dev);
} }
cntlid = nvme_subsys_register_ctrl(n, errp); cntlid = nvme_subsys_register_ctrl(n, errp);
@ -8950,7 +8956,6 @@ static void nvme_exit(PCIDevice *pci_dev)
nvme_ctrl_reset(n, NVME_RESET_FUNCTION); nvme_ctrl_reset(n, NVME_RESET_FUNCTION);
if (n->subsys) {
for (i = 1; i <= NVME_MAX_NAMESPACES; i++) { for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
ns = nvme_ns(n, i); ns = nvme_ns(n, i);
if (ns) { if (ns) {
@ -8959,7 +8964,6 @@ static void nvme_exit(PCIDevice *pci_dev)
} }
nvme_subsys_unregister_ctrl(n->subsys, n); nvme_subsys_unregister_ctrl(n->subsys, n);
}
g_free(n->cq); g_free(n->cq);
g_free(n->sq); g_free(n->sq);

View file

@ -727,25 +727,14 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
uint32_t nsid = ns->params.nsid; uint32_t nsid = ns->params.nsid;
int i; int i;
if (!n->subsys) { assert(subsys);
/* If no subsys, the ns cannot be attached to more than one ctrl. */
ns->params.shared = false; /* reparent to subsystem bus */
if (ns->params.detached) {
error_setg(errp, "detached requires that the nvme device is "
"linked to an nvme-subsys device");
return;
}
} else {
/*
* If this namespace belongs to a subsystem (through a link on the
* controller device), reparent the device.
*/
if (!qdev_set_parent_bus(dev, &subsys->bus.parent_bus, errp)) { if (!qdev_set_parent_bus(dev, &subsys->bus.parent_bus, errp)) {
return; return;
} }
ns->subsys = subsys; ns->subsys = subsys;
ns->endgrp = &subsys->endgrp; ns->endgrp = &subsys->endgrp;
}
if (nvme_ns_setup(ns, errp)) { if (nvme_ns_setup(ns, errp)) {
return; return;
@ -753,7 +742,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
if (!nsid) { if (!nsid) {
for (i = 1; i <= NVME_MAX_NAMESPACES; i++) { for (i = 1; i <= NVME_MAX_NAMESPACES; i++) {
if (nvme_ns(n, i) || nvme_subsys_ns(subsys, i)) { if (nvme_subsys_ns(subsys, i)) {
continue; continue;
} }
@ -765,14 +754,11 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
error_setg(errp, "no free namespace id"); error_setg(errp, "no free namespace id");
return; return;
} }
} else { } else if (nvme_subsys_ns(subsys, nsid)) {
if (nvme_ns(n, nsid) || nvme_subsys_ns(subsys, nsid)) {
error_setg(errp, "namespace id '%d' already allocated", nsid); error_setg(errp, "namespace id '%d' already allocated", nsid);
return; return;
} }
}
if (subsys) {
subsys->namespaces[nsid] = ns; subsys->namespaces[nsid] = ns;
ns->id_ns.endgid = cpu_to_le16(0x1); ns->id_ns.endgid = cpu_to_le16(0x1);
@ -790,13 +776,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
nvme_attach_ns(ctrl, ns); nvme_attach_ns(ctrl, ns);
} }
} }
return;
} }
}
nvme_attach_ns(n, ns);
} }
static const Property nvme_ns_props[] = { static const Property nvme_ns_props[] = {