[PATCH v2] hw/nvme: i/o cmd set independent namespace data structure

Arun Kumar posted 1 patch 3 weeks, 6 days ago
hw/nvme/ctrl.c       | 31 +++++++++++++++++++++++++++++++
hw/nvme/ns.c         |  6 +++++-
hw/nvme/nvme.h       |  1 +
hw/nvme/trace-events |  1 +
include/block/nvme.h | 22 ++++++++++++++++++++--
5 files changed, 58 insertions(+), 3 deletions(-)
[PATCH v2] hw/nvme: i/o cmd set independent namespace data structure
Posted by Arun Kumar 3 weeks, 6 days ago
add support for i/o command set independent namespace data
structure(cns=8h and cns=1fh)

Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
Signed-off-by: Arun Kumar <arun.kka@samsung.com>
---
 hw/nvme/ctrl.c       | 31 +++++++++++++++++++++++++++++++
 hw/nvme/ns.c         |  6 +++++-
 hw/nvme/nvme.h       |  1 +
 hw/nvme/trace-events |  1 +
 include/block/nvme.h | 22 ++++++++++++++++++++--
 5 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 127c3d2383..cef2c3fa19 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -5498,6 +5498,33 @@ static uint16_t nvme_identify_sec_ctrl_list(NvmeCtrl *n, NvmeRequest *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,
                                      bool active)
 {
@@ -5732,6 +5759,10 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeRequest *req)
         return nvme_identify_sec_ctrl_list(n, req);
     case NVME_ID_CNS_CS_NS:
         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:
         return nvme_identify_ns_csi(n, req, false);
     case NVME_ID_CNS_CTRL:
diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c
index ea8db175db..6dbdcb49bf 100644
--- a/hw/nvme/ns.c
+++ b/hw/nvme/ns.c
@@ -62,6 +62,7 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
     static uint64_t ns_count;
     NvmeIdNs *id_ns = &ns->id_ns;
     NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm;
+    NvmeIdNsInd *id_ns_ind = &ns->id_ns_ind;
     uint8_t ds;
     uint16_t ms;
     int i;
@@ -75,7 +76,9 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
     id_ns->nsfeat |= (0x4 | 0x10);
 
     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 */
@@ -770,6 +773,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
         subsys->namespaces[nsid] = ns;
 
         ns->id_ns.endgid = cpu_to_le16(0x1);
+        ns->id_ns_ind.endgrpid = cpu_to_le16(0x1);
 
         if (ns->params.detached) {
             return;
diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h
index bed8191bd5..b0268efe84 100644
--- a/hw/nvme/nvme.h
+++ b/hw/nvme/nvme.h
@@ -228,6 +228,7 @@ typedef struct NvmeNamespace {
     int64_t      moff;
     NvmeIdNs     id_ns;
     NvmeIdNsNvm  id_ns_nvm;
+    NvmeIdNsInd  id_ns_ind;
     NvmeLBAF     lbaf;
     unsigned int nlbaf;
     size_t       lbasz;
diff --git a/hw/nvme/trace-events b/hw/nvme/trace-events
index 3a67680c6a..6be0bfa1c1 100644
--- a/hw/nvme/trace-events
+++ b/hw/nvme/trace-events
@@ -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_csi(uint8_t csi) "identify controller, csi=0x%"PRIx8""
 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_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""
diff --git a/include/block/nvme.h b/include/block/nvme.h
index bb231d0b9a..47af651354 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -1068,6 +1068,7 @@ enum NvmeIdCns {
     NVME_ID_CNS_CS_NS                 = 0x05,
     NVME_ID_CNS_CS_CTRL               = 0x06,
     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            = 0x11,
     NVME_ID_CNS_NS_ATTACHED_CTRL_LIST = 0x12,
@@ -1077,6 +1078,7 @@ enum NvmeIdCns {
     NVME_ID_CNS_CS_NS_PRESENT_LIST    = 0x1a,
     NVME_ID_CNS_CS_NS_PRESENT         = 0x1b,
     NVME_ID_CNS_IO_COMMAND_SET        = 0x1c,
+    NVME_ID_CNS_CS_IND_NS_ALLOCATED   = 0x1f,
 };
 
 typedef struct QEMU_PACKED NvmeIdCtrl {
@@ -1400,6 +1402,20 @@ typedef struct QEMU_PACKED NvmeIdNsNvm {
     uint8_t     rsvd268[3828];
 } 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 {
     uint8_t nidt;
     uint8_t nidl;
@@ -1420,8 +1436,9 @@ enum NvmeNsIdentifierType {
     NVME_NIDT_CSI               = 0x04,
 };
 
-enum NvmeIdNsNmic {
-    NVME_NMIC_NS_SHARED         = 1 << 0,
+enum NvmeIdNsIndependent {
+    NVME_ID_NS_IND_NMIC_SHRNS   = 0x01,
+    NVME_ID_NS_IND_NSTAT_NRDY   = 0x01,
 };
 
 enum NvmeCsi {
@@ -1854,6 +1871,7 @@ static inline void _nvme_check_size(void)
     QEMU_BUILD_BUG_ON(sizeof(NvmeLBAF) != 4);
     QEMU_BUILD_BUG_ON(sizeof(NvmeLBAFE) != 16);
     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(NvmeIdNsZoned) != 4096);
     QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
-- 
2.43.0
Re: [PATCH v2] hw/nvme: i/o cmd set independent namespace data structure
Posted by Klaus Jensen 1 week, 6 days ago
On Sep 25 06:14, Arun Kumar wrote:
> add support for i/o command set independent namespace data
> structure(cns=8h and cns=1fh)
> 
> Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
> Signed-off-by: Arun Kumar <arun.kka@samsung.com>

Looks good.

Reviewed-by: Klaus Jensen <k.jensen@samsung.com>

> ---
>  hw/nvme/ctrl.c       | 31 +++++++++++++++++++++++++++++++
>  hw/nvme/ns.c         |  6 +++++-
>  hw/nvme/nvme.h       |  1 +
>  hw/nvme/trace-events |  1 +
>  include/block/nvme.h | 22 ++++++++++++++++++++--
>  5 files changed, 58 insertions(+), 3 deletions(-)
> 
> diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
> index 127c3d2383..cef2c3fa19 100644
> --- a/hw/nvme/ctrl.c
> +++ b/hw/nvme/ctrl.c
> @@ -5498,6 +5498,33 @@ static uint16_t nvme_identify_sec_ctrl_list(NvmeCtrl *n, NvmeRequest *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,
>                                       bool active)
>  {
> @@ -5732,6 +5759,10 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeRequest *req)
>          return nvme_identify_sec_ctrl_list(n, req);
>      case NVME_ID_CNS_CS_NS:
>          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:
>          return nvme_identify_ns_csi(n, req, false);
>      case NVME_ID_CNS_CTRL:
> diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c
> index ea8db175db..6dbdcb49bf 100644
> --- a/hw/nvme/ns.c
> +++ b/hw/nvme/ns.c
> @@ -62,6 +62,7 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
>      static uint64_t ns_count;
>      NvmeIdNs *id_ns = &ns->id_ns;
>      NvmeIdNsNvm *id_ns_nvm = &ns->id_ns_nvm;
> +    NvmeIdNsInd *id_ns_ind = &ns->id_ns_ind;
>      uint8_t ds;
>      uint16_t ms;
>      int i;
> @@ -75,7 +76,9 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
>      id_ns->nsfeat |= (0x4 | 0x10);
>  
>      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 */
> @@ -770,6 +773,7 @@ static void nvme_ns_realize(DeviceState *dev, Error **errp)
>          subsys->namespaces[nsid] = ns;
>  
>          ns->id_ns.endgid = cpu_to_le16(0x1);
> +        ns->id_ns_ind.endgrpid = cpu_to_le16(0x1);
>  
>          if (ns->params.detached) {
>              return;
> diff --git a/hw/nvme/nvme.h b/hw/nvme/nvme.h
> index bed8191bd5..b0268efe84 100644
> --- a/hw/nvme/nvme.h
> +++ b/hw/nvme/nvme.h
> @@ -228,6 +228,7 @@ typedef struct NvmeNamespace {
>      int64_t      moff;
>      NvmeIdNs     id_ns;
>      NvmeIdNsNvm  id_ns_nvm;
> +    NvmeIdNsInd  id_ns_ind;
>      NvmeLBAF     lbaf;
>      unsigned int nlbaf;
>      size_t       lbasz;
> diff --git a/hw/nvme/trace-events b/hw/nvme/trace-events
> index 3a67680c6a..6be0bfa1c1 100644
> --- a/hw/nvme/trace-events
> +++ b/hw/nvme/trace-events
> @@ -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_csi(uint8_t csi) "identify controller, csi=0x%"PRIx8""
>  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_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""
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index bb231d0b9a..47af651354 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -1068,6 +1068,7 @@ enum NvmeIdCns {
>      NVME_ID_CNS_CS_NS                 = 0x05,
>      NVME_ID_CNS_CS_CTRL               = 0x06,
>      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            = 0x11,
>      NVME_ID_CNS_NS_ATTACHED_CTRL_LIST = 0x12,
> @@ -1077,6 +1078,7 @@ enum NvmeIdCns {
>      NVME_ID_CNS_CS_NS_PRESENT_LIST    = 0x1a,
>      NVME_ID_CNS_CS_NS_PRESENT         = 0x1b,
>      NVME_ID_CNS_IO_COMMAND_SET        = 0x1c,
> +    NVME_ID_CNS_CS_IND_NS_ALLOCATED   = 0x1f,
>  };
>  
>  typedef struct QEMU_PACKED NvmeIdCtrl {
> @@ -1400,6 +1402,20 @@ typedef struct QEMU_PACKED NvmeIdNsNvm {
>      uint8_t     rsvd268[3828];
>  } 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 {
>      uint8_t nidt;
>      uint8_t nidl;
> @@ -1420,8 +1436,9 @@ enum NvmeNsIdentifierType {
>      NVME_NIDT_CSI               = 0x04,
>  };
>  
> -enum NvmeIdNsNmic {
> -    NVME_NMIC_NS_SHARED         = 1 << 0,
> +enum NvmeIdNsIndependent {
> +    NVME_ID_NS_IND_NMIC_SHRNS   = 0x01,
> +    NVME_ID_NS_IND_NSTAT_NRDY   = 0x01,
>  };
>  
>  enum NvmeCsi {
> @@ -1854,6 +1871,7 @@ static inline void _nvme_check_size(void)
>      QEMU_BUILD_BUG_ON(sizeof(NvmeLBAF) != 4);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeLBAFE) != 16);
>      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(NvmeIdNsZoned) != 4096);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
> -- 
> 2.43.0
> 
>