2021-01-24 02:54:45 +00:00
|
|
|
/*
|
|
|
|
* QEMU NVM Express Subsystem: nvme-subsys
|
|
|
|
*
|
|
|
|
* Copyright (c) 2021 Minwoo Im <minwoo.im.dev@gmail.com>
|
|
|
|
*
|
|
|
|
* This code is licensed under the GNU GPL v2. Refer COPYING.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef NVME_SUBSYS_H
|
|
|
|
#define NVME_SUBSYS_H
|
|
|
|
|
|
|
|
#define TYPE_NVME_SUBSYS "nvme-subsys"
|
|
|
|
#define NVME_SUBSYS(obj) \
|
|
|
|
OBJECT_CHECK(NvmeSubsystem, (obj), TYPE_NVME_SUBSYS)
|
|
|
|
|
|
|
|
#define NVME_SUBSYS_MAX_CTRLS 32
|
2021-02-05 17:09:20 +00:00
|
|
|
#define NVME_SUBSYS_MAX_NAMESPACES 256
|
2021-01-24 02:54:45 +00:00
|
|
|
|
|
|
|
typedef struct NvmeCtrl NvmeCtrl;
|
|
|
|
typedef struct NvmeNamespace NvmeNamespace;
|
|
|
|
typedef struct NvmeSubsystem {
|
|
|
|
DeviceState parent_obj;
|
|
|
|
uint8_t subnqn[256];
|
|
|
|
|
2021-01-24 02:54:48 +00:00
|
|
|
NvmeCtrl *ctrls[NVME_SUBSYS_MAX_CTRLS];
|
hw/block/nvme: support namespace detach
Given that now we have nvme-subsys device supported, we can manage
namespace allocated, but not attached: detached. This patch introduced
a parameter for nvme-ns device named 'detached'. This parameter
indicates whether the given namespace device is detached from
a entire NVMe subsystem('subsys' given case, shared namespace) or a
controller('bus' given case, private namespace).
- Allocated namespace
1) Shared ns in the subsystem 'subsys0':
-device nvme-ns,id=ns1,drive=blknvme0,nsid=1,subsys=subsys0,detached=true
2) Private ns for the controller 'nvme0' of the subsystem 'subsys0':
-device nvme-subsys,id=subsys0
-device nvme,serial=foo,id=nvme0,subsys=subsys0
-device nvme-ns,id=ns1,drive=blknvme0,nsid=1,bus=nvme0,detached=true
3) (Invalid case) Controller 'nvme0' has no subsystem to manage ns:
-device nvme,serial=foo,id=nvme0
-device nvme-ns,id=ns1,drive=blknvme0,nsid=1,bus=nvme0,detached=true
Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
2021-02-05 15:30:10 +00:00
|
|
|
/* Allocated namespaces for this subsystem */
|
2021-02-05 17:03:20 +00:00
|
|
|
NvmeNamespace *namespaces[NVME_SUBSYS_MAX_NAMESPACES + 1];
|
2021-01-24 02:54:48 +00:00
|
|
|
|
2021-01-24 02:54:45 +00:00
|
|
|
struct {
|
|
|
|
char *nqn;
|
|
|
|
} params;
|
|
|
|
} NvmeSubsystem;
|
|
|
|
|
2021-01-24 02:54:48 +00:00
|
|
|
int nvme_subsys_register_ctrl(NvmeCtrl *n, Error **errp);
|
hw/block/nvme: support for shared namespace in subsystem
nvme-ns device is registered to a nvme controller device during the
initialization in nvme_register_namespace() in case that 'bus' property
is given which means it's mapped to a single controller.
This patch introduced a new property 'subsys' just like the controller
device instance did to map a namespace to a NVMe subsystem.
If 'subsys' property is given to the nvme-ns device, it will belong to
the specified subsystem and will be attached to all controllers in that
subsystem by enabling shared namespace capability in NMIC(Namespace
Multi-path I/O and Namespace Capabilities) in Identify Namespace.
Usage:
-device nvme-subsys,id=subsys0
-device nvme,serial=foo,id=nvme0,subsys=subsys0
-device nvme,serial=bar,id=nvme1,subsys=subsys0
-device nvme,serial=baz,id=nvme2,subsys=subsys0
-device nvme-ns,id=ns1,drive=<drv>,nsid=1,subsys=subsys0 # Shared
-device nvme-ns,id=ns2,drive=<drv>,nsid=2,bus=nvme2 # Non-shared
In the above example, 'ns1' will be shared to 'nvme0' and 'nvme1' in
the same subsystem. On the other hand, 'ns2' will be attached to the
'nvme2' only as a private namespace in that subsystem.
All the namespace with 'subsys' parameter will attach all controllers in
the subsystem to the namespace by default.
Signed-off-by: Minwoo Im <minwoo.im.dev@gmail.com>
Tested-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
2021-01-24 02:54:50 +00:00
|
|
|
int nvme_subsys_register_ns(NvmeNamespace *ns, Error **errp);
|
2021-01-24 02:54:48 +00:00
|
|
|
|
2021-02-06 03:18:09 +00:00
|
|
|
static inline NvmeCtrl *nvme_subsys_ctrl(NvmeSubsystem *subsys,
|
|
|
|
uint32_t cntlid)
|
|
|
|
{
|
|
|
|
if (!subsys) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return subsys->ctrls[cntlid];
|
|
|
|
}
|
|
|
|
|
2021-02-05 17:15:10 +00:00
|
|
|
/*
|
|
|
|
* Return allocated namespace of the specified nsid in the subsystem.
|
|
|
|
*/
|
|
|
|
static inline NvmeNamespace *nvme_subsys_ns(NvmeSubsystem *subsys,
|
|
|
|
uint32_t nsid)
|
|
|
|
{
|
|
|
|
if (!subsys) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-03-15 07:41:41 +00:00
|
|
|
assert(nsid && nsid <= NVME_SUBSYS_MAX_NAMESPACES);
|
|
|
|
|
2021-02-05 17:15:10 +00:00
|
|
|
return subsys->namespaces[nsid];
|
|
|
|
}
|
|
|
|
|
2021-01-24 02:54:45 +00:00
|
|
|
#endif /* NVME_SUBSYS_H */
|