diff mbox series

[v11,08/13] block/nvme: Make ZNS-related definitions

Message ID 20201208200410.27900-9-dmitry.fomichev@wdc.com (mailing list archive)
State New, archived
Headers show
Series hw/block/nvme: Support Namespace Types and Zoned Namespace Command Set | expand

Commit Message

Dmitry Fomichev Dec. 8, 2020, 8:04 p.m. UTC
Define values and structures that are needed to support Zoned
Namespace Command Set (NVMe TP 4053).

Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
---
 include/block/nvme.h | 114 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 113 insertions(+), 1 deletion(-)

Comments

Klaus Jensen Dec. 9, 2020, 6:37 a.m. UTC | #1
CC for Stefan (nvme block driver co-maintainer).

On Dec  9 05:04, Dmitry Fomichev wrote:
> Define values and structures that are needed to support Zoned
> Namespace Command Set (NVMe TP 4053).
> 
> Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
> ---
>  include/block/nvme.h | 114 ++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 113 insertions(+), 1 deletion(-)
> 
> diff --git a/include/block/nvme.h b/include/block/nvme.h
> index 29d826ab19..a9165402d6 100644
> --- a/include/block/nvme.h
> +++ b/include/block/nvme.h
> @@ -489,6 +489,9 @@ enum NvmeIoCommands {
>      NVME_CMD_COMPARE            = 0x05,
>      NVME_CMD_WRITE_ZEROES       = 0x08,
>      NVME_CMD_DSM                = 0x09,
> +    NVME_CMD_ZONE_MGMT_SEND     = 0x79,
> +    NVME_CMD_ZONE_MGMT_RECV     = 0x7a,
> +    NVME_CMD_ZONE_APPEND        = 0x7d,
>  };
>  
>  typedef struct QEMU_PACKED NvmeDeleteQ {
> @@ -648,9 +651,13 @@ typedef struct QEMU_PACKED NvmeAerResult {
>      uint8_t resv;
>  } NvmeAerResult;
>  
> +typedef struct QEMU_PACKED NvmeZonedResult {
> +    uint64_t slba;
> +} NvmeZonedResult;
> +
>  typedef struct QEMU_PACKED NvmeCqe {
>      uint32_t    result;
> -    uint32_t    rsvd;
> +    uint32_t    dw1;
>      uint16_t    sq_head;
>      uint16_t    sq_id;
>      uint16_t    cid;
> @@ -679,6 +686,7 @@ enum NvmeStatusCodes {
>      NVME_INVALID_USE_OF_CMB     = 0x0012,
>      NVME_INVALID_PRP_OFFSET     = 0x0013,
>      NVME_CMD_SET_CMB_REJECTED   = 0x002b,
> +    NVME_INVALID_CMD_SET        = 0x002c,
>      NVME_LBA_RANGE              = 0x0080,
>      NVME_CAP_EXCEEDED           = 0x0081,
>      NVME_NS_NOT_READY           = 0x0082,
> @@ -703,6 +711,14 @@ enum NvmeStatusCodes {
>      NVME_CONFLICTING_ATTRS      = 0x0180,
>      NVME_INVALID_PROT_INFO      = 0x0181,
>      NVME_WRITE_TO_RO            = 0x0182,
> +    NVME_ZONE_BOUNDARY_ERROR    = 0x01b8,
> +    NVME_ZONE_FULL              = 0x01b9,
> +    NVME_ZONE_READ_ONLY         = 0x01ba,
> +    NVME_ZONE_OFFLINE           = 0x01bb,
> +    NVME_ZONE_INVALID_WRITE     = 0x01bc,
> +    NVME_ZONE_TOO_MANY_ACTIVE   = 0x01bd,
> +    NVME_ZONE_TOO_MANY_OPEN     = 0x01be,
> +    NVME_ZONE_INVAL_TRANSITION  = 0x01bf,
>      NVME_WRITE_FAULT            = 0x0280,
>      NVME_UNRECOVERED_READ       = 0x0281,
>      NVME_E2E_GUARD_ERROR        = 0x0282,
> @@ -888,6 +904,11 @@ typedef struct QEMU_PACKED NvmeIdCtrl {
>      uint8_t     vs[1024];
>  } NvmeIdCtrl;
>  
> +typedef struct NvmeIdCtrlZoned {
> +    uint8_t     zasl;
> +    uint8_t     rsvd1[4095];
> +} NvmeIdCtrlZoned;
> +
>  enum NvmeIdCtrlOacs {
>      NVME_OACS_SECURITY  = 1 << 0,
>      NVME_OACS_FORMAT    = 1 << 1,
> @@ -1016,6 +1037,12 @@ typedef struct QEMU_PACKED NvmeLBAF {
>      uint8_t     rp;
>  } NvmeLBAF;
>  
> +typedef struct QEMU_PACKED NvmeLBAFE {
> +    uint64_t    zsze;
> +    uint8_t     zdes;
> +    uint8_t     rsvd9[7];
> +} NvmeLBAFE;
> +
>  #define NVME_NSID_BROADCAST 0xffffffff
>  
>  typedef struct QEMU_PACKED NvmeIdNs {
> @@ -1075,10 +1102,24 @@ enum NvmeNsIdentifierType {
>  
>  enum NvmeCsi {
>      NVME_CSI_NVM                = 0x00,
> +    NVME_CSI_ZONED              = 0x02,
>  };
>  
>  #define NVME_SET_CSI(vec, csi) (vec |= (uint8_t)(1 << (csi)))
>  
> +typedef struct QEMU_PACKED NvmeIdNsZoned {
> +    uint16_t    zoc;
> +    uint16_t    ozcs;
> +    uint32_t    mar;
> +    uint32_t    mor;
> +    uint32_t    rrl;
> +    uint32_t    frl;
> +    uint8_t     rsvd20[2796];
> +    NvmeLBAFE   lbafe[16];
> +    uint8_t     rsvd3072[768];
> +    uint8_t     vs[256];
> +} NvmeIdNsZoned;
> +
>  /*Deallocate Logical Block Features*/
>  #define NVME_ID_NS_DLFEAT_GUARD_CRC(dlfeat)       ((dlfeat) & 0x10)
>  #define NVME_ID_NS_DLFEAT_WRITE_ZEROES(dlfeat)    ((dlfeat) & 0x08)
> @@ -1111,10 +1152,76 @@ enum NvmeIdNsDps {
>      DPS_FIRST_EIGHT = 8,
>  };
>  
> +enum NvmeZoneAttr {
> +    NVME_ZA_FINISHED_BY_CTLR         = 1 << 0,
> +    NVME_ZA_FINISH_RECOMMENDED       = 1 << 1,
> +    NVME_ZA_RESET_RECOMMENDED        = 1 << 2,
> +    NVME_ZA_ZD_EXT_VALID             = 1 << 7,
> +};
> +
> +typedef struct QEMU_PACKED NvmeZoneReportHeader {
> +    uint64_t    nr_zones;
> +    uint8_t     rsvd[56];
> +} NvmeZoneReportHeader;
> +
> +enum NvmeZoneReceiveAction {
> +    NVME_ZONE_REPORT                 = 0,
> +    NVME_ZONE_REPORT_EXTENDED        = 1,
> +};
> +
> +enum NvmeZoneReportType {
> +    NVME_ZONE_REPORT_ALL             = 0,
> +    NVME_ZONE_REPORT_EMPTY           = 1,
> +    NVME_ZONE_REPORT_IMPLICITLY_OPEN = 2,
> +    NVME_ZONE_REPORT_EXPLICITLY_OPEN = 3,
> +    NVME_ZONE_REPORT_CLOSED          = 4,
> +    NVME_ZONE_REPORT_FULL            = 5,
> +    NVME_ZONE_REPORT_READ_ONLY       = 6,
> +    NVME_ZONE_REPORT_OFFLINE         = 7,
> +};
> +
> +enum NvmeZoneType {
> +    NVME_ZONE_TYPE_RESERVED          = 0x00,
> +    NVME_ZONE_TYPE_SEQ_WRITE         = 0x02,
> +};
> +
> +enum NvmeZoneSendAction {
> +    NVME_ZONE_ACTION_RSD             = 0x00,
> +    NVME_ZONE_ACTION_CLOSE           = 0x01,
> +    NVME_ZONE_ACTION_FINISH          = 0x02,
> +    NVME_ZONE_ACTION_OPEN            = 0x03,
> +    NVME_ZONE_ACTION_RESET           = 0x04,
> +    NVME_ZONE_ACTION_OFFLINE         = 0x05,
> +    NVME_ZONE_ACTION_SET_ZD_EXT      = 0x10,
> +};
> +
> +typedef struct QEMU_PACKED NvmeZoneDescr {
> +    uint8_t     zt;
> +    uint8_t     zs;
> +    uint8_t     za;
> +    uint8_t     rsvd3[5];
> +    uint64_t    zcap;
> +    uint64_t    zslba;
> +    uint64_t    wp;
> +    uint8_t     rsvd32[32];
> +} NvmeZoneDescr;
> +
> +enum NvmeZoneState {
> +    NVME_ZONE_STATE_RESERVED         = 0x00,
> +    NVME_ZONE_STATE_EMPTY            = 0x01,
> +    NVME_ZONE_STATE_IMPLICITLY_OPEN  = 0x02,
> +    NVME_ZONE_STATE_EXPLICITLY_OPEN  = 0x03,
> +    NVME_ZONE_STATE_CLOSED           = 0x04,
> +    NVME_ZONE_STATE_READ_ONLY        = 0x0D,
> +    NVME_ZONE_STATE_FULL             = 0x0E,
> +    NVME_ZONE_STATE_OFFLINE          = 0x0F,
> +};
> +
>  static inline void _nvme_check_size(void)
>  {
>      QEMU_BUILD_BUG_ON(sizeof(NvmeBar) != 4096);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeAerResult) != 4);
> +    QEMU_BUILD_BUG_ON(sizeof(NvmeZonedResult) != 8);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
> @@ -1130,8 +1237,13 @@ static inline void _nvme_check_size(void)
>      QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeEffectsLog) != 4096);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
> +    QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrlZoned) != 4096);
> +    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(NvmeIdNsZoned) != 4096);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
>      QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsDescr) != 4);
> +    QEMU_BUILD_BUG_ON(sizeof(NvmeZoneDescr) != 64);
>  }
>  #endif
> -- 
> 2.28.0
> 
>
Stefan Hajnoczi Dec. 15, 2020, 4:28 p.m. UTC | #2
On Wed, Dec 09, 2020 at 07:37:11AM +0100, Klaus Jensen wrote:
> CC for Stefan (nvme block driver co-maintainer).
> 
> On Dec  9 05:04, Dmitry Fomichev wrote:
> > Define values and structures that are needed to support Zoned
> > Namespace Command Set (NVMe TP 4053).
> > 
> > Signed-off-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
> > ---
> >  include/block/nvme.h | 114 ++++++++++++++++++++++++++++++++++++++++++-
> >  1 file changed, 113 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/block/nvme.h b/include/block/nvme.h
> > index 29d826ab19..a9165402d6 100644
> > --- a/include/block/nvme.h
> > +++ b/include/block/nvme.h
> > @@ -489,6 +489,9 @@ enum NvmeIoCommands {
> >      NVME_CMD_COMPARE            = 0x05,
> >      NVME_CMD_WRITE_ZEROES       = 0x08,
> >      NVME_CMD_DSM                = 0x09,
> > +    NVME_CMD_ZONE_MGMT_SEND     = 0x79,
> > +    NVME_CMD_ZONE_MGMT_RECV     = 0x7a,
> > +    NVME_CMD_ZONE_APPEND        = 0x7d,
> >  };
> >  
> >  typedef struct QEMU_PACKED NvmeDeleteQ {
> > @@ -648,9 +651,13 @@ typedef struct QEMU_PACKED NvmeAerResult {
> >      uint8_t resv;
> >  } NvmeAerResult;
> >  
> > +typedef struct QEMU_PACKED NvmeZonedResult {
> > +    uint64_t slba;
> > +} NvmeZonedResult;
> > +
> >  typedef struct QEMU_PACKED NvmeCqe {
> >      uint32_t    result;
> > -    uint32_t    rsvd;
> > +    uint32_t    dw1;
> >      uint16_t    sq_head;
> >      uint16_t    sq_id;
> >      uint16_t    cid;
> > @@ -679,6 +686,7 @@ enum NvmeStatusCodes {
> >      NVME_INVALID_USE_OF_CMB     = 0x0012,
> >      NVME_INVALID_PRP_OFFSET     = 0x0013,
> >      NVME_CMD_SET_CMB_REJECTED   = 0x002b,
> > +    NVME_INVALID_CMD_SET        = 0x002c,
> >      NVME_LBA_RANGE              = 0x0080,
> >      NVME_CAP_EXCEEDED           = 0x0081,
> >      NVME_NS_NOT_READY           = 0x0082,
> > @@ -703,6 +711,14 @@ enum NvmeStatusCodes {
> >      NVME_CONFLICTING_ATTRS      = 0x0180,
> >      NVME_INVALID_PROT_INFO      = 0x0181,
> >      NVME_WRITE_TO_RO            = 0x0182,
> > +    NVME_ZONE_BOUNDARY_ERROR    = 0x01b8,
> > +    NVME_ZONE_FULL              = 0x01b9,
> > +    NVME_ZONE_READ_ONLY         = 0x01ba,
> > +    NVME_ZONE_OFFLINE           = 0x01bb,
> > +    NVME_ZONE_INVALID_WRITE     = 0x01bc,
> > +    NVME_ZONE_TOO_MANY_ACTIVE   = 0x01bd,
> > +    NVME_ZONE_TOO_MANY_OPEN     = 0x01be,
> > +    NVME_ZONE_INVAL_TRANSITION  = 0x01bf,
> >      NVME_WRITE_FAULT            = 0x0280,
> >      NVME_UNRECOVERED_READ       = 0x0281,
> >      NVME_E2E_GUARD_ERROR        = 0x0282,
> > @@ -888,6 +904,11 @@ typedef struct QEMU_PACKED NvmeIdCtrl {
> >      uint8_t     vs[1024];
> >  } NvmeIdCtrl;
> >  
> > +typedef struct NvmeIdCtrlZoned {
> > +    uint8_t     zasl;
> > +    uint8_t     rsvd1[4095];
> > +} NvmeIdCtrlZoned;
> > +
> >  enum NvmeIdCtrlOacs {
> >      NVME_OACS_SECURITY  = 1 << 0,
> >      NVME_OACS_FORMAT    = 1 << 1,
> > @@ -1016,6 +1037,12 @@ typedef struct QEMU_PACKED NvmeLBAF {
> >      uint8_t     rp;
> >  } NvmeLBAF;
> >  
> > +typedef struct QEMU_PACKED NvmeLBAFE {
> > +    uint64_t    zsze;
> > +    uint8_t     zdes;
> > +    uint8_t     rsvd9[7];
> > +} NvmeLBAFE;
> > +
> >  #define NVME_NSID_BROADCAST 0xffffffff
> >  
> >  typedef struct QEMU_PACKED NvmeIdNs {
> > @@ -1075,10 +1102,24 @@ enum NvmeNsIdentifierType {
> >  
> >  enum NvmeCsi {
> >      NVME_CSI_NVM                = 0x00,
> > +    NVME_CSI_ZONED              = 0x02,
> >  };
> >  
> >  #define NVME_SET_CSI(vec, csi) (vec |= (uint8_t)(1 << (csi)))
> >  
> > +typedef struct QEMU_PACKED NvmeIdNsZoned {
> > +    uint16_t    zoc;
> > +    uint16_t    ozcs;
> > +    uint32_t    mar;
> > +    uint32_t    mor;
> > +    uint32_t    rrl;
> > +    uint32_t    frl;
> > +    uint8_t     rsvd20[2796];
> > +    NvmeLBAFE   lbafe[16];
> > +    uint8_t     rsvd3072[768];
> > +    uint8_t     vs[256];
> > +} NvmeIdNsZoned;
> > +
> >  /*Deallocate Logical Block Features*/
> >  #define NVME_ID_NS_DLFEAT_GUARD_CRC(dlfeat)       ((dlfeat) & 0x10)
> >  #define NVME_ID_NS_DLFEAT_WRITE_ZEROES(dlfeat)    ((dlfeat) & 0x08)
> > @@ -1111,10 +1152,76 @@ enum NvmeIdNsDps {
> >      DPS_FIRST_EIGHT = 8,
> >  };
> >  
> > +enum NvmeZoneAttr {
> > +    NVME_ZA_FINISHED_BY_CTLR         = 1 << 0,
> > +    NVME_ZA_FINISH_RECOMMENDED       = 1 << 1,
> > +    NVME_ZA_RESET_RECOMMENDED        = 1 << 2,
> > +    NVME_ZA_ZD_EXT_VALID             = 1 << 7,
> > +};
> > +
> > +typedef struct QEMU_PACKED NvmeZoneReportHeader {
> > +    uint64_t    nr_zones;
> > +    uint8_t     rsvd[56];
> > +} NvmeZoneReportHeader;
> > +
> > +enum NvmeZoneReceiveAction {
> > +    NVME_ZONE_REPORT                 = 0,
> > +    NVME_ZONE_REPORT_EXTENDED        = 1,
> > +};
> > +
> > +enum NvmeZoneReportType {
> > +    NVME_ZONE_REPORT_ALL             = 0,
> > +    NVME_ZONE_REPORT_EMPTY           = 1,
> > +    NVME_ZONE_REPORT_IMPLICITLY_OPEN = 2,
> > +    NVME_ZONE_REPORT_EXPLICITLY_OPEN = 3,
> > +    NVME_ZONE_REPORT_CLOSED          = 4,
> > +    NVME_ZONE_REPORT_FULL            = 5,
> > +    NVME_ZONE_REPORT_READ_ONLY       = 6,
> > +    NVME_ZONE_REPORT_OFFLINE         = 7,
> > +};
> > +
> > +enum NvmeZoneType {
> > +    NVME_ZONE_TYPE_RESERVED          = 0x00,
> > +    NVME_ZONE_TYPE_SEQ_WRITE         = 0x02,
> > +};
> > +
> > +enum NvmeZoneSendAction {
> > +    NVME_ZONE_ACTION_RSD             = 0x00,
> > +    NVME_ZONE_ACTION_CLOSE           = 0x01,
> > +    NVME_ZONE_ACTION_FINISH          = 0x02,
> > +    NVME_ZONE_ACTION_OPEN            = 0x03,
> > +    NVME_ZONE_ACTION_RESET           = 0x04,
> > +    NVME_ZONE_ACTION_OFFLINE         = 0x05,
> > +    NVME_ZONE_ACTION_SET_ZD_EXT      = 0x10,
> > +};
> > +
> > +typedef struct QEMU_PACKED NvmeZoneDescr {
> > +    uint8_t     zt;
> > +    uint8_t     zs;
> > +    uint8_t     za;
> > +    uint8_t     rsvd3[5];
> > +    uint64_t    zcap;
> > +    uint64_t    zslba;
> > +    uint64_t    wp;
> > +    uint8_t     rsvd32[32];
> > +} NvmeZoneDescr;
> > +
> > +enum NvmeZoneState {
> > +    NVME_ZONE_STATE_RESERVED         = 0x00,
> > +    NVME_ZONE_STATE_EMPTY            = 0x01,
> > +    NVME_ZONE_STATE_IMPLICITLY_OPEN  = 0x02,
> > +    NVME_ZONE_STATE_EXPLICITLY_OPEN  = 0x03,
> > +    NVME_ZONE_STATE_CLOSED           = 0x04,
> > +    NVME_ZONE_STATE_READ_ONLY        = 0x0D,
> > +    NVME_ZONE_STATE_FULL             = 0x0E,
> > +    NVME_ZONE_STATE_OFFLINE          = 0x0F,
> > +};
> > +
> >  static inline void _nvme_check_size(void)
> >  {
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeBar) != 4096);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeAerResult) != 4);
> > +    QEMU_BUILD_BUG_ON(sizeof(NvmeZonedResult) != 8);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
> > @@ -1130,8 +1237,13 @@ static inline void _nvme_check_size(void)
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeEffectsLog) != 4096);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
> > +    QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrlZoned) != 4096);
> > +    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(NvmeIdNsZoned) != 4096);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
> >      QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsDescr) != 4);
> > +    QEMU_BUILD_BUG_ON(sizeof(NvmeZoneDescr) != 64);
> >  }
> >  #endif
> > -- 
> > 2.28.0
> > 
> > 
> 
> -- 
> One of us - No more doubt, silence or taboo about mental illness.



Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
diff mbox series

Patch

diff --git a/include/block/nvme.h b/include/block/nvme.h
index 29d826ab19..a9165402d6 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -489,6 +489,9 @@  enum NvmeIoCommands {
     NVME_CMD_COMPARE            = 0x05,
     NVME_CMD_WRITE_ZEROES       = 0x08,
     NVME_CMD_DSM                = 0x09,
+    NVME_CMD_ZONE_MGMT_SEND     = 0x79,
+    NVME_CMD_ZONE_MGMT_RECV     = 0x7a,
+    NVME_CMD_ZONE_APPEND        = 0x7d,
 };
 
 typedef struct QEMU_PACKED NvmeDeleteQ {
@@ -648,9 +651,13 @@  typedef struct QEMU_PACKED NvmeAerResult {
     uint8_t resv;
 } NvmeAerResult;
 
+typedef struct QEMU_PACKED NvmeZonedResult {
+    uint64_t slba;
+} NvmeZonedResult;
+
 typedef struct QEMU_PACKED NvmeCqe {
     uint32_t    result;
-    uint32_t    rsvd;
+    uint32_t    dw1;
     uint16_t    sq_head;
     uint16_t    sq_id;
     uint16_t    cid;
@@ -679,6 +686,7 @@  enum NvmeStatusCodes {
     NVME_INVALID_USE_OF_CMB     = 0x0012,
     NVME_INVALID_PRP_OFFSET     = 0x0013,
     NVME_CMD_SET_CMB_REJECTED   = 0x002b,
+    NVME_INVALID_CMD_SET        = 0x002c,
     NVME_LBA_RANGE              = 0x0080,
     NVME_CAP_EXCEEDED           = 0x0081,
     NVME_NS_NOT_READY           = 0x0082,
@@ -703,6 +711,14 @@  enum NvmeStatusCodes {
     NVME_CONFLICTING_ATTRS      = 0x0180,
     NVME_INVALID_PROT_INFO      = 0x0181,
     NVME_WRITE_TO_RO            = 0x0182,
+    NVME_ZONE_BOUNDARY_ERROR    = 0x01b8,
+    NVME_ZONE_FULL              = 0x01b9,
+    NVME_ZONE_READ_ONLY         = 0x01ba,
+    NVME_ZONE_OFFLINE           = 0x01bb,
+    NVME_ZONE_INVALID_WRITE     = 0x01bc,
+    NVME_ZONE_TOO_MANY_ACTIVE   = 0x01bd,
+    NVME_ZONE_TOO_MANY_OPEN     = 0x01be,
+    NVME_ZONE_INVAL_TRANSITION  = 0x01bf,
     NVME_WRITE_FAULT            = 0x0280,
     NVME_UNRECOVERED_READ       = 0x0281,
     NVME_E2E_GUARD_ERROR        = 0x0282,
@@ -888,6 +904,11 @@  typedef struct QEMU_PACKED NvmeIdCtrl {
     uint8_t     vs[1024];
 } NvmeIdCtrl;
 
+typedef struct NvmeIdCtrlZoned {
+    uint8_t     zasl;
+    uint8_t     rsvd1[4095];
+} NvmeIdCtrlZoned;
+
 enum NvmeIdCtrlOacs {
     NVME_OACS_SECURITY  = 1 << 0,
     NVME_OACS_FORMAT    = 1 << 1,
@@ -1016,6 +1037,12 @@  typedef struct QEMU_PACKED NvmeLBAF {
     uint8_t     rp;
 } NvmeLBAF;
 
+typedef struct QEMU_PACKED NvmeLBAFE {
+    uint64_t    zsze;
+    uint8_t     zdes;
+    uint8_t     rsvd9[7];
+} NvmeLBAFE;
+
 #define NVME_NSID_BROADCAST 0xffffffff
 
 typedef struct QEMU_PACKED NvmeIdNs {
@@ -1075,10 +1102,24 @@  enum NvmeNsIdentifierType {
 
 enum NvmeCsi {
     NVME_CSI_NVM                = 0x00,
+    NVME_CSI_ZONED              = 0x02,
 };
 
 #define NVME_SET_CSI(vec, csi) (vec |= (uint8_t)(1 << (csi)))
 
+typedef struct QEMU_PACKED NvmeIdNsZoned {
+    uint16_t    zoc;
+    uint16_t    ozcs;
+    uint32_t    mar;
+    uint32_t    mor;
+    uint32_t    rrl;
+    uint32_t    frl;
+    uint8_t     rsvd20[2796];
+    NvmeLBAFE   lbafe[16];
+    uint8_t     rsvd3072[768];
+    uint8_t     vs[256];
+} NvmeIdNsZoned;
+
 /*Deallocate Logical Block Features*/
 #define NVME_ID_NS_DLFEAT_GUARD_CRC(dlfeat)       ((dlfeat) & 0x10)
 #define NVME_ID_NS_DLFEAT_WRITE_ZEROES(dlfeat)    ((dlfeat) & 0x08)
@@ -1111,10 +1152,76 @@  enum NvmeIdNsDps {
     DPS_FIRST_EIGHT = 8,
 };
 
+enum NvmeZoneAttr {
+    NVME_ZA_FINISHED_BY_CTLR         = 1 << 0,
+    NVME_ZA_FINISH_RECOMMENDED       = 1 << 1,
+    NVME_ZA_RESET_RECOMMENDED        = 1 << 2,
+    NVME_ZA_ZD_EXT_VALID             = 1 << 7,
+};
+
+typedef struct QEMU_PACKED NvmeZoneReportHeader {
+    uint64_t    nr_zones;
+    uint8_t     rsvd[56];
+} NvmeZoneReportHeader;
+
+enum NvmeZoneReceiveAction {
+    NVME_ZONE_REPORT                 = 0,
+    NVME_ZONE_REPORT_EXTENDED        = 1,
+};
+
+enum NvmeZoneReportType {
+    NVME_ZONE_REPORT_ALL             = 0,
+    NVME_ZONE_REPORT_EMPTY           = 1,
+    NVME_ZONE_REPORT_IMPLICITLY_OPEN = 2,
+    NVME_ZONE_REPORT_EXPLICITLY_OPEN = 3,
+    NVME_ZONE_REPORT_CLOSED          = 4,
+    NVME_ZONE_REPORT_FULL            = 5,
+    NVME_ZONE_REPORT_READ_ONLY       = 6,
+    NVME_ZONE_REPORT_OFFLINE         = 7,
+};
+
+enum NvmeZoneType {
+    NVME_ZONE_TYPE_RESERVED          = 0x00,
+    NVME_ZONE_TYPE_SEQ_WRITE         = 0x02,
+};
+
+enum NvmeZoneSendAction {
+    NVME_ZONE_ACTION_RSD             = 0x00,
+    NVME_ZONE_ACTION_CLOSE           = 0x01,
+    NVME_ZONE_ACTION_FINISH          = 0x02,
+    NVME_ZONE_ACTION_OPEN            = 0x03,
+    NVME_ZONE_ACTION_RESET           = 0x04,
+    NVME_ZONE_ACTION_OFFLINE         = 0x05,
+    NVME_ZONE_ACTION_SET_ZD_EXT      = 0x10,
+};
+
+typedef struct QEMU_PACKED NvmeZoneDescr {
+    uint8_t     zt;
+    uint8_t     zs;
+    uint8_t     za;
+    uint8_t     rsvd3[5];
+    uint64_t    zcap;
+    uint64_t    zslba;
+    uint64_t    wp;
+    uint8_t     rsvd32[32];
+} NvmeZoneDescr;
+
+enum NvmeZoneState {
+    NVME_ZONE_STATE_RESERVED         = 0x00,
+    NVME_ZONE_STATE_EMPTY            = 0x01,
+    NVME_ZONE_STATE_IMPLICITLY_OPEN  = 0x02,
+    NVME_ZONE_STATE_EXPLICITLY_OPEN  = 0x03,
+    NVME_ZONE_STATE_CLOSED           = 0x04,
+    NVME_ZONE_STATE_READ_ONLY        = 0x0D,
+    NVME_ZONE_STATE_FULL             = 0x0E,
+    NVME_ZONE_STATE_OFFLINE          = 0x0F,
+};
+
 static inline void _nvme_check_size(void)
 {
     QEMU_BUILD_BUG_ON(sizeof(NvmeBar) != 4096);
     QEMU_BUILD_BUG_ON(sizeof(NvmeAerResult) != 4);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeZonedResult) != 8);
     QEMU_BUILD_BUG_ON(sizeof(NvmeCqe) != 16);
     QEMU_BUILD_BUG_ON(sizeof(NvmeDsmRange) != 16);
     QEMU_BUILD_BUG_ON(sizeof(NvmeCmd) != 64);
@@ -1130,8 +1237,13 @@  static inline void _nvme_check_size(void)
     QEMU_BUILD_BUG_ON(sizeof(NvmeSmartLog) != 512);
     QEMU_BUILD_BUG_ON(sizeof(NvmeEffectsLog) != 4096);
     QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrl) != 4096);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeIdCtrlZoned) != 4096);
+    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(NvmeIdNsZoned) != 4096);
     QEMU_BUILD_BUG_ON(sizeof(NvmeSglDescriptor) != 16);
     QEMU_BUILD_BUG_ON(sizeof(NvmeIdNsDescr) != 4);
+    QEMU_BUILD_BUG_ON(sizeof(NvmeZoneDescr) != 64);
 }
 #endif