xemu/hw/block/nvme-subsys.h

63 lines
1.4 KiB
C
Raw Normal View History

/*
* 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
#define NVME_SUBSYS_MAX_NAMESPACES 256
typedef struct NvmeCtrl NvmeCtrl;
typedef struct NvmeNamespace NvmeNamespace;
typedef struct NvmeSubsystem {
DeviceState parent_obj;
uint8_t subnqn[256];
NvmeCtrl *ctrls[NVME_SUBSYS_MAX_CTRLS];
/* Allocated namespaces for this subsystem */
NvmeNamespace *namespaces[NVME_SUBSYS_MAX_NAMESPACES + 1];
struct {
char *nqn;
} params;
} NvmeSubsystem;
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);
static inline NvmeCtrl *nvme_subsys_ctrl(NvmeSubsystem *subsys,
uint32_t cntlid)
{
if (!subsys) {
return NULL;
}
return subsys->ctrls[cntlid];
}
/*
* 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;
}
assert(nsid && nsid <= NVME_SUBSYS_MAX_NAMESPACES);
return subsys->namespaces[nsid];
}
#endif /* NVME_SUBSYS_H */