diff options
Diffstat (limited to 'hw/block/nvme.c')
-rw-r--r-- | hw/block/nvme.c | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/hw/block/nvme.c b/hw/block/nvme.c index bfab80c457..1790a66cb8 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -27,7 +27,7 @@ * subsys=<subsys_id> * -device nvme-ns,drive=<drive_id>,bus=<bus_name>,nsid=<nsid>,\ * zoned=<true|false[optional]>, \ - * subsys=<subsys_id> + * subsys=<subsys_id>,detached=<true|false[optional]> * * Note cmb_size_mb denotes size of CMB in MB. CMB is assumed to be at * offset 0 in BAR2 and supports only WDS, RDS and SQS for now. By default, the @@ -91,6 +91,13 @@ * subsystem. Otherwise, `bus` must be given to attach this namespace to a * specific controller as a non-shared namespace. * + * - `detached` + * This parameter is only valid together with the `subsys` parameter. If left + * at the default value (`false/off`), the namespace will be attached to all + * controllers in the NVMe subsystem at boot-up. If set to `true/on`, the + * namespace will be be available in the subsystem not not attached to any + * controllers. + * * Setting `zoned` to true selects Zoned Command Set at the namespace. * In this case, the following namespace properties are available to configure * zoned operation: @@ -4655,6 +4662,20 @@ static void nvme_init_state(NvmeCtrl *n) n->aer_reqs = g_new0(NvmeRequest *, n->params.aerl + 1); } +static int nvme_attach_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp) +{ + if (nvme_ns_is_attached(n, ns)) { + error_setg(errp, + "namespace %d is already attached to controller %d", + nvme_nsid(ns), n->cntlid); + return -1; + } + + nvme_ns_attach(n, ns); + + return 0; +} + int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp) { uint32_t nsid = nvme_nsid(ns); @@ -4686,7 +4707,23 @@ int nvme_register_namespace(NvmeCtrl *n, NvmeNamespace *ns, Error **errp) trace_pci_nvme_register_namespace(nsid); - n->namespaces[nsid - 1] = ns; + /* + * If subsys is not given, namespae is always attached to the controller + * because there's no subsystem to manage namespace allocation. + */ + if (!n->subsys) { + if (ns->params.detached) { + error_setg(errp, + "detached needs nvme-subsys specified nvme or nvme-ns"); + return -1; + } + + return nvme_attach_namespace(n, ns, errp); + } else { + if (!ns->params.detached) { + return nvme_attach_namespace(n, ns, errp); + } + } n->dmrsl = MIN_NON_ZERO(n->dmrsl, BDRV_REQUEST_MAX_BYTES / nvme_l2b(ns, 1)); |