hw/nvme: i/o cmd set independent namespace data structure

Add support for the I/O Command Set Independent Namespace Data
Structure (CNS 8h and 1fh).

Signed-off-by: Arun Kumar <arun.kka@samsung.com>
Reviewed-by: Klaus Jensen <k.jensen@samsung.com>
Link: https://lore.kernel.org/r/20240925004407.3521406-1-arun.kka@samsung.com
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
This commit is contained in:
Arun Kumar 2024-09-25 06:14:07 +05:30 committed by Klaus Jensen
parent daaf51001a
commit 79e490058f
5 changed files with 59 additions and 3 deletions

View File

@ -5692,6 +5692,33 @@ static uint16_t nvme_identify_sec_ctrl_list(NvmeCtrl *n, NvmeRequest *req)
return nvme_c2h(n, (uint8_t *)&list, sizeof(list), req); return nvme_c2h(n, (uint8_t *)&list, sizeof(list), req);
} }
static uint16_t nvme_identify_ns_ind(NvmeCtrl *n, NvmeRequest *req, bool alloc)
{
NvmeNamespace *ns;
NvmeIdentify *c = (NvmeIdentify *)&req->cmd;
uint32_t nsid = le32_to_cpu(c->nsid);
trace_pci_nvme_identify_ns_ind(nsid);
if (!nvme_nsid_valid(n, nsid) || nsid == NVME_NSID_BROADCAST) {
return NVME_INVALID_NSID | NVME_DNR;
}
ns = nvme_ns(n, nsid);
if (unlikely(!ns)) {
if (alloc) {
ns = nvme_subsys_ns(n->subsys, nsid);
if (!ns) {
return nvme_rpt_empty_id_struct(n, req);
}
} else {
return nvme_rpt_empty_id_struct(n, req);
}
}
return nvme_c2h(n, (uint8_t *)&ns->id_ns_ind, sizeof(NvmeIdNsInd), req);
}
static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, NvmeRequest *req, static uint16_t nvme_identify_ns_csi(NvmeCtrl *n, NvmeRequest *req,
bool active) bool active)
{ {
@ -5946,6 +5973,10 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeRequest *req)
return nvme_identify_sec_ctrl_list(n, req); return nvme_identify_sec_ctrl_list(n, req);
case NVME_ID_CNS_CS_NS: case NVME_ID_CNS_CS_NS:
return nvme_identify_ns_csi(n, req, true); return nvme_identify_ns_csi(n, req, true);
case NVME_ID_CNS_CS_IND_NS:
return nvme_identify_ns_ind(n, req, false);
case NVME_ID_CNS_CS_IND_NS_ALLOCATED:
return nvme_identify_ns_ind(n, req, true);
case NVME_ID_CNS_CS_NS_PRESENT: case NVME_ID_CNS_CS_NS_PRESENT:
return nvme_identify_ns_csi(n, req, false); return nvme_identify_ns_csi(n, req, false);
case NVME_ID_CNS_CTRL: case NVME_ID_CNS_CTRL:

View File

@ -62,6 +62,7 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
static uint64_t ns_count; static uint64_t ns_count;
NvmeIdNs *id_ns = &ns->id_ns; NvmeIdNs *id_ns = &ns->id_ns;
NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm; NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm;
NvmeIdNsInd *id_ns_ind = &ns->id_ns_ind;
uint8_t ds; uint8_t ds;
uint16_t ms; uint16_t ms;
int i; int i;
@ -75,7 +76,9 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
id_ns->nsfeat |= (0x4 | 0x10); id_ns->nsfeat |= (0x4 | 0x10);
if (ns->params.shared) { if (ns->params.shared) {
id_ns->nmic |= NVME_NMIC_NS_SHARED; id_ns->nmic |= NVME_ID_NS_IND_NMIC_SHRNS;
id_ns_ind->nmic = NVME_ID_NS_IND_NMIC_SHRNS;
id_ns_ind->nstat = NVME_ID_NS_IND_NSTAT_NRDY;
} }
/* Substitute a missing EUI-64 by an autogenerated one */ /* Substitute a missing EUI-64 by an autogenerated one */
@ -770,6 +773,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
subsys->namespaces[nsid] = ns; subsys->namespaces[nsid] = ns;
ns->id_ns.endgid = cpu_to_le16(0x1); ns->id_ns.endgid = cpu_to_le16(0x1);
ns->id_ns_ind.endgrpid = cpu_to_le16(0x1);
if (ns->params.detached) { if (ns->params.detached) {
return; return;

View File

@ -233,6 +233,7 @@ typedef struct NvmeNamespace {
int64_t moff; int64_t moff;
NvmeIdNs id_ns; NvmeIdNs id_ns;
NvmeIdNsNvm id_ns_nvm; NvmeIdNsNvm id_ns_nvm;
NvmeIdNsInd id_ns_ind;
NvmeLBAF lbaf; NvmeLBAF lbaf;
unsigned int nlbaf; unsigned int nlbaf;
size_t lbasz; size_t lbasz;

View File

@ -56,6 +56,7 @@ pci_nvme_identify(uint16_t cid, uint8_t cns, uint16_t ctrlid, uint8_t csi) "cid
pci_nvme_identify_ctrl(void) "identify controller" pci_nvme_identify_ctrl(void) "identify controller"
pci_nvme_identify_ctrl_csi(uint8_t csi) "identify controller, csi=0x%"PRIx8"" pci_nvme_identify_ctrl_csi(uint8_t csi) "identify controller, csi=0x%"PRIx8""
pci_nvme_identify_ns(uint32_t ns) "nsid %"PRIu32"" pci_nvme_identify_ns(uint32_t ns) "nsid %"PRIu32""
pci_nvme_identify_ns_ind(uint32_t nsid) "nsid %"PRIu32""
pci_nvme_identify_ctrl_list(uint8_t cns, uint16_t cntid) "cns 0x%"PRIx8" cntid %"PRIu16"" pci_nvme_identify_ctrl_list(uint8_t cns, uint16_t cntid) "cns 0x%"PRIx8" cntid %"PRIu16""
pci_nvme_identify_pri_ctrl_cap(uint16_t cntlid) "identify primary controller capabilities cntlid=%"PRIu16"" pci_nvme_identify_pri_ctrl_cap(uint16_t cntlid) "identify primary controller capabilities cntlid=%"PRIu16""
pci_nvme_identify_sec_ctrl_list(uint16_t cntlid, uint8_t numcntl) "identify secondary controller list cntlid=%"PRIu16" numcntl=%"PRIu8"" pci_nvme_identify_sec_ctrl_list(uint16_t cntlid, uint8_t numcntl) "identify secondary controller list cntlid=%"PRIu16" numcntl=%"PRIu8""

View File

@ -1077,6 +1077,7 @@ enum NvmeIdCns {
NVME_ID_CNS_CS_NS = 0x05, NVME_ID_CNS_CS_NS = 0x05,
NVME_ID_CNS_CS_CTRL = 0x06, NVME_ID_CNS_CS_CTRL = 0x06,
NVME_ID_CNS_CS_NS_ACTIVE_LIST = 0x07, NVME_ID_CNS_CS_NS_ACTIVE_LIST = 0x07,
NVME_ID_CNS_CS_IND_NS = 0x08,
NVME_ID_CNS_NS_PRESENT_LIST = 0x10, NVME_ID_CNS_NS_PRESENT_LIST = 0x10,
NVME_ID_CNS_NS_PRESENT = 0x11, NVME_ID_CNS_NS_PRESENT = 0x11,
NVME_ID_CNS_NS_ATTACHED_CTRL_LIST = 0x12, NVME_ID_CNS_NS_ATTACHED_CTRL_LIST = 0x12,
@ -1087,6 +1088,7 @@ enum NvmeIdCns {
NVME_ID_CNS_CS_NS_PRESENT_LIST = 0x1a, NVME_ID_CNS_CS_NS_PRESENT_LIST = 0x1a,
NVME_ID_CNS_CS_NS_PRESENT = 0x1b, NVME_ID_CNS_CS_NS_PRESENT = 0x1b,
NVME_ID_CNS_IO_COMMAND_SET = 0x1c, NVME_ID_CNS_IO_COMMAND_SET = 0x1c,
NVME_ID_CNS_CS_IND_NS_ALLOCATED = 0x1f,
}; };
typedef struct QEMU_PACKED NvmeIdCtrl { typedef struct QEMU_PACKED NvmeIdCtrl {
@ -1419,6 +1421,20 @@ typedef struct QEMU_PACKED NvmeIdNsNvm {
uint8_t rsvd268[3828]; uint8_t rsvd268[3828];
} NvmeIdNsNvm; } NvmeIdNsNvm;
typedef struct QEMU_PACKED NvmeIdNsInd {
uint8_t nsfeat;
uint8_t nmic;
uint8_t rescap;
uint8_t fpi;
uint32_t anagrpid;
uint8_t nsattr;
uint8_t rsvd9;
uint16_t nvmsetid;
uint16_t endgrpid;
uint8_t nstat;
uint8_t rsvd15[4081];
} NvmeIdNsInd;
typedef struct QEMU_PACKED NvmeIdNsDescr { typedef struct QEMU_PACKED NvmeIdNsDescr {
uint8_t nidt; uint8_t nidt;
uint8_t nidl; uint8_t nidl;
@ -1439,8 +1455,10 @@ enum NvmeNsIdentifierType {
NVME_NIDT_CSI = 0x04, NVME_NIDT_CSI = 0x04,
}; };
enum NvmeIdNsNmic { enum NvmeIdNsIndependent {
NVME_NMIC_NS_SHARED = 1 << 0, NVME_ID_NS_IND_NMIC_SHRNS = 1 << 0,
NVME_ID_NS_IND_NMIC_DISNS = 1 << 1,
NVME_ID_NS_IND_NSTAT_NRDY = 1 << 0,
}; };
enum NvmeCsi { enum NvmeCsi {
@ -1873,6 +1891,7 @@ static inline void _nvme_check_size(void)
QEMU_BUILD_BUG_ON(sizeof(NvmeLBAF) != 4); QEMU_BUILD_BUG_ON(sizeof(NvmeLBAF) != 4);
QEMU_BUILD_BUG_ON(sizeof(NvmeLBAFE) != 16); QEMU_BUILD_BUG_ON(sizeof(NvmeLBAFE) != 16);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096); QEMU_BUILD_BUG_ON(sizeof(NvmeIdNs) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsInd) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsNvm) != 4096); QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsNvm) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsZoned) != 4096); QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsZoned) != 4096);
QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16); QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);