1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
  14  * Copyright (c) 2018, Joyent, Inc.
  15  */
  16 
  17 /*
  18  * NVMe hardware interface
  19  */
  20 
  21 #ifndef _NVME_REG_H
  22 #define _NVME_REG_H
  23 
  24 #include <sys/nvme.h>
  25 
  26 #pragma pack(1)
  27 
  28 #ifdef __cplusplus
  29 extern "C" {
  30 #endif
  31 
  32 
  33 /*
  34  * NVMe constants
  35  */
  36 #define NVME_MAX_ADMIN_QUEUE_LEN        4096
  37 
  38 /*
  39  * NVMe registers and register fields
  40  */
  41 #define NVME_REG_CAP    0x0             /* Controller Capabilities */
  42 #define NVME_REG_VS     0x8             /* Version */
  43 #define NVME_REG_INTMS  0xc             /* Interrupt Mask Set */
  44 #define NVME_REG_INTMC  0x10            /* Interrupt Mask Clear */
  45 #define NVME_REG_CC     0x14            /* Controller Configuration */
  46 #define NVME_REG_CSTS   0x1c            /* Controller Status */
  47 #define NVME_REG_NSSR   0x20            /* NVM Subsystem Reset */
  48 #define NVME_REG_AQA    0x24            /* Admin Queue Attributes */
  49 #define NVME_REG_ASQ    0x28            /* Admin Submission Queue */
  50 #define NVME_REG_ACQ    0x30            /* Admin Completion Qeueu */
  51 #define NVME_REG_CMBLOC 0x38            /* Controller Memory Buffer Location */
  52 #define NVME_REG_CMBSZ  0x3C            /* Controller Memory Buffer Size */
  53 #define NVME_REG_BPINFO 0x40            /* Boot Partition Information */
  54 #define NVME_REG_BPRSEL 0x44            /* Boot Partition Read Select */
  55 #define NVME_REG_BPMBL  0x48            /* Boot Partition Memory Buffer Loc */
  56 #define NVME_REG_SQTDBL(nvme, n) \
  57         (0x1000 + ((2 * (n)) * nvme->n_doorbell_stride))
  58 #define NVME_REG_CQHDBL(nvme, n) \
  59         (0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride))
  60 
  61 #define  NVME_CAP_CSS_NVM       1       /* NVM Command Set */
  62 #define  NVME_CAP_AMS_WRR       1       /* Weighted Round-Robin */
  63 
  64 /* CAP -- Controller Capabilities */
  65 typedef union {
  66         struct {
  67                 uint16_t cap_mqes;      /* Maximum Queue Entries Supported */
  68                 uint8_t cap_cqr:1;      /* Contiguous Queues Required */
  69                 uint8_t cap_ams:2;      /* Arbitration Mechanisms Supported */
  70                 uint8_t cap_rsvd1:5;
  71                 uint8_t cap_to;         /* Timeout */
  72                 uint16_t cap_dstrd:4;   /* Doorbell Stride */
  73                 uint16_t cap_nssrs:1;   /* NVM Subsystem Reset Supported */
  74                 uint16_t cap_css:8;     /* Command Sets Supported */
  75                 uint16_t cap_rsvd2:2;
  76                 uint8_t cap_bps:1;      /* Boot Partition Support */
  77                 uint8_t cap_mpsmin:4;   /* Memory Page Size Minimum */
  78                 uint8_t cap_mpsmax:4;   /* Memory Page Size Maximum */
  79                 uint8_t cap_rsvd3;
  80         } b;
  81         uint64_t r;
  82 } nvme_reg_cap_t;
  83 
  84 /* VS -- Version */
  85 typedef union {
  86         struct {
  87                 uint8_t vs_rsvd;
  88                 uint8_t vs_mnr;         /* Minor Version Number */
  89                 uint16_t vs_mjr;        /* Major Version Number */
  90         } b;
  91         uint32_t r;
  92 } nvme_reg_vs_t;
  93 
  94 /* CC -- Controller Configuration */
  95 #define NVME_CC_SHN_NORMAL      1       /* Normal Shutdown Notification */
  96 #define NVME_CC_SHN_ABRUPT      2       /* Abrupt Shutdown Notification */
  97 
  98 typedef union {
  99         struct {
 100                 uint16_t cc_en:1;       /* Enable */
 101                 uint16_t cc_rsvd1:3;
 102                 uint16_t cc_css:3;      /* I/O Command Set Selected */
 103                 uint16_t cc_mps:4;      /* Memory Page Size */
 104                 uint16_t cc_ams:3;      /* Arbitration Mechanism Selected */
 105                 uint16_t cc_shn:2;      /* Shutdown Notification */
 106                 uint8_t cc_iosqes:4;    /* I/O Submission Queue Entry Size */
 107                 uint8_t cc_iocqes:4;    /* I/O Completion Queue Entry Size */
 108                 uint8_t cc_rsvd2;
 109         } b;
 110         uint32_t r;
 111 } nvme_reg_cc_t;
 112 
 113 /* CSTS -- Controller Status */
 114 #define NVME_CSTS_SHN_OCCURING  1       /* Shutdown Processing Occuring */
 115 #define NVME_CSTS_SHN_COMPLETE  2       /* Shutdown Processing Complete */
 116 
 117 typedef union {
 118         struct {
 119                 uint32_t csts_rdy:1;    /* Ready */
 120                 uint32_t csts_cfs:1;    /* Controller Fatal Status */
 121                 uint32_t csts_shst:2;   /* Shutdown Status */
 122                 uint32_t csts_nssro:1;  /* NVM Subsystem Reset Occured */
 123                 uint32_t csts_pp:1;     /* Processing Paused */
 124                 uint32_t csts_rsvd:26;
 125         } b;
 126         uint32_t r;
 127 } nvme_reg_csts_t;
 128 
 129 /* NSSR -- NVM Subsystem Reset */
 130 #define NVME_NSSR_NSSRC 0x4e564d65      /* NSSR magic value */
 131 typedef uint32_t nvme_reg_nssr_t;
 132 
 133 /* AQA -- Admin Queue Attributes */
 134 typedef union {
 135         struct {
 136                 uint16_t aqa_asqs:12;   /* Admin Submission Queue Size */
 137                 uint16_t aqa_rsvd1:4;
 138                 uint16_t aqa_acqs:12;   /* Admin Completion Queue Size */
 139                 uint16_t aqa_rsvd2:4;
 140         } b;
 141         uint32_t r;
 142 } nvme_reg_aqa_t;
 143 
 144 /*
 145  * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is
 146  * probably a specification bug. The full 64bit regs are used as base address,
 147  * and the lower bits must be zero to ensure alignment on the page size
 148  * specified in CC.MPS.
 149  */
 150 /* ASQ -- Admin Submission Queue Base Address */
 151 typedef uint64_t nvme_reg_asq_t;        /* Admin Submission Queue Base */
 152 
 153 /* ACQ -- Admin Completion Queue Base Address */
 154 typedef uint64_t nvme_reg_acq_t;        /* Admin Completion Queue Base */
 155 
 156 /* CMBLOC - Controller Memory Buffer Location */
 157 typedef union {
 158         struct {
 159                 uint32_t cmbloc_bir:3;          /* Base Indicator Register */
 160                 uint32_t cmbloc_rsvd:9;
 161                 uint32_t cmbloc_ofst:20;        /* Offset */
 162         } b;
 163         uint32_t r;
 164 } nvme_reg_cmbloc_t;
 165 
 166 /* CMBSZ - Controller Memory Buffer Size */
 167 typedef union {
 168         struct {
 169                 uint32_t cmbsz_sqs:1;   /* Submission Queue Support */
 170                 uint32_t cmbsz_cqs:1;   /* Completion Queue Support */
 171                 uint32_t cmbsz_lists:1; /* PRP SGL List Support */
 172                 uint32_t cmbsz_rds:1;   /* Read Data Support */
 173                 uint32_t cmbsz_wds:1;   /* Write Data Support */
 174                 uint32_t cmbsz_rsvd:3;
 175                 uint32_t cmbsz_szu:4;   /* Size Units */
 176                 uint32_t cmbsz_sz:20;   /* Size */
 177         } b;
 178         uint32_t r;
 179 } nvme_reg_cmbsz_t;
 180 
 181 /* BPINFO - Boot Partition Information */
 182 typedef union {
 183         struct {
 184                 uint32_t bpinfo_bpsz:15;        /* Boot Partition Size */
 185                 uint32_t bpinfo_rsvd:9;
 186                 uint32_t bpinfo_brs:2;          /* Boot Read Status */
 187                 uint32_t bpinfo_rsvd2:5;
 188                 uint32_t bpinfo_abpid:1;        /* Active Boot Partition ID */
 189         } b;
 190         uint32_t r;
 191 } nvme_reg_bpinfo_t;
 192 
 193 /* BPRSEL - Boot Partition Read Select */
 194 typedef union {
 195         struct {
 196                 uint32_t bprsel_bprsz:10;       /* Boot Partition Read Size */
 197                 uint32_t bprsel_bprof:20;       /* Boot Partition Read Offset */
 198                 uint32_t bprsel_rsvd:1;
 199                 uint32_t bprsel_bpid:1;         /* Boot Partition Identifier */
 200         } b;
 201         uint32_t r;
 202 } nvme_reg_bprsel_t;
 203 
 204 /* BPMBL - Boot Partition Memory Location Buffer Location */
 205 typedef uint64_t nvme_reg_bpbml_t;      /* Memory Buffer Base Address */
 206 
 207 /* SQyTDBL -- Submission Queue y Tail Doorbell */
 208 typedef union {
 209         struct {
 210                 uint16_t sqtdbl_sqt;    /* Submission Queue Tail */
 211                 uint16_t sqtdbl_rsvd;
 212         } b;
 213         uint32_t r;
 214 } nvme_reg_sqtdbl_t;
 215 
 216 /* CQyHDBL -- Completion Queue y Head Doorbell */
 217 typedef union {
 218         struct {
 219                 uint16_t cqhdbl_cqh;    /* Completion Queue Head */
 220                 uint16_t cqhdbl_rsvd;
 221         } b;
 222         uint32_t r;
 223 } nvme_reg_cqhdbl_t;
 224 
 225 /*
 226  * NVMe submission queue entries
 227  */
 228 
 229 /* NVMe scatter/gather list descriptor */
 230 typedef struct {
 231         uint64_t sgl_addr;              /* Address */
 232         uint32_t sgl_len;               /* Length */
 233         uint8_t sgl_rsvd[3];
 234         uint8_t sgl_zero:4;
 235         uint8_t sgl_type:4;             /* SGL descriptor type */
 236 } nvme_sgl_t;
 237 
 238 /* NVMe SGL descriptor type */
 239 #define NVME_SGL_DATA_BLOCK     0
 240 #define NVME_SGL_BIT_BUCKET     1
 241 #define NVME_SGL_SEGMENT        2
 242 #define NVME_SGL_LAST_SEGMENT   3
 243 #define NVME_SGL_VENDOR         0xf
 244 
 245 /* NVMe submission queue entry */
 246 typedef struct {
 247         uint8_t sqe_opc;                /* Opcode */
 248         uint8_t sqe_fuse:2;             /* Fused Operation */
 249         uint8_t sqe_rsvd:5;
 250         uint8_t sqe_psdt:1;             /* PRP or SGL for Data Transfer */
 251         uint16_t sqe_cid;               /* Command Identifier */
 252         uint32_t sqe_nsid;              /* Namespace Identifier */
 253         uint64_t sqe_rsvd1;
 254         union {
 255                 uint64_t m_ptr;         /* Metadata Pointer */
 256                 uint64_t m_sglp;        /* Metadata SGL Segment Pointer */
 257         } sqe_m;
 258         union {
 259                 uint64_t d_prp[2];      /* Physical Page Region Entries 1 & 2 */
 260                 nvme_sgl_t d_sgl;       /* SGL Entry 1 */
 261         } sqe_dptr;                     /* Data Pointer */
 262         uint32_t sqe_cdw10;             /* Number of Dwords in Data Transfer */
 263         uint32_t sqe_cdw11;             /* Number of Dwords in Metadata Xfer */
 264         uint32_t sqe_cdw12;
 265         uint32_t sqe_cdw13;
 266         uint32_t sqe_cdw14;
 267         uint32_t sqe_cdw15;
 268 } nvme_sqe_t;
 269 
 270 /* NVMe admin command opcodes */
 271 #define NVME_OPC_DELETE_SQUEUE  0x0
 272 #define NVME_OPC_CREATE_SQUEUE  0x1
 273 #define NVME_OPC_GET_LOG_PAGE   0x2
 274 #define NVME_OPC_DELETE_CQUEUE  0x4
 275 #define NVME_OPC_CREATE_CQUEUE  0x5
 276 #define NVME_OPC_IDENTIFY       0x6
 277 #define NVME_OPC_ABORT          0x8
 278 #define NVME_OPC_SET_FEATURES   0x9
 279 #define NVME_OPC_GET_FEATURES   0xa
 280 #define NVME_OPC_ASYNC_EVENT    0xc
 281 #define NVME_OPC_NS_MGMT        0xd     /* 1.2 */
 282 #define NVME_OPC_FW_ACTIVATE    0x10
 283 #define NVME_OPC_FW_IMAGE_LOAD  0x11
 284 #define NVME_OPC_SELF_TEST      0x14    /* 1.3 */
 285 #define NVME_OPC_NS_ATTACH      0x15    /* 1.2 */
 286 #define NVME_OPC_KEEP_ALIVE     0x18    /* 1.3 */
 287 #define NVME_OPC_DIRECTIVE_SEND 0x19    /* 1.3 */
 288 #define NVME_OPC_DIRECTIVE_RECV 0x1A    /* 1.3 */
 289 #define NVME_OPC_VIRT_MGMT      0x1C    /* 1.3 */
 290 #define NVME_OPC_NVMEMI_SEND    0x1D    /* 1.3 */
 291 #define NVME_OPC_NVMEMI_RECV    0x1E    /* 1.3 */
 292 #define NVME_OPC_DB_CONFIG      0x7C    /* 1.3 */
 293 
 294 /* NVMe NVM command set specific admin command opcodes */
 295 #define NVME_OPC_NVM_FORMAT     0x80
 296 #define NVME_OPC_NVM_SEC_SEND   0x81
 297 #define NVME_OPC_NVM_SEC_RECV   0x82
 298 
 299 /* NVMe NVM command opcodes */
 300 #define NVME_OPC_NVM_FLUSH      0x0
 301 #define NVME_OPC_NVM_WRITE      0x1
 302 #define NVME_OPC_NVM_READ       0x2
 303 #define NVME_OPC_NVM_WRITE_UNC  0x4
 304 #define NVME_OPC_NVM_COMPARE    0x5
 305 #define NVME_OPC_NVM_WRITE_ZERO 0x8
 306 #define NVME_OPC_NVM_DSET_MGMT  0x9
 307 #define NVME_OPC_NVM_RESV_REG   0xd
 308 #define NVME_OPC_NVM_RESV_REPRT 0xe
 309 #define NVME_OPC_NVM_RESV_ACQ   0x11
 310 #define NVME_OPC_NVM_RESV_REL   0x12
 311 
 312 /*
 313  * NVMe completion queue entry
 314  */
 315 typedef struct {
 316         uint32_t cqe_dw0;               /* Command Specific */
 317         uint32_t cqe_rsvd1;
 318         uint16_t cqe_sqhd;              /* SQ Head Pointer */
 319         uint16_t cqe_sqid;              /* SQ Identifier */
 320         uint16_t cqe_cid;               /* Command Identifier */
 321         nvme_cqe_sf_t cqe_sf;           /* Status Field */
 322 } nvme_cqe_t;
 323 
 324 /* NVMe completion status code type */
 325 #define NVME_CQE_SCT_GENERIC    0       /* Generic Command Status */
 326 #define NVME_CQE_SCT_SPECIFIC   1       /* Command Specific Status */
 327 #define NVME_CQE_SCT_INTEGRITY  2       /* Media and Data Integrity Errors */
 328 #define NVME_CQE_SCT_VENDOR     7       /* Vendor Specific */
 329 
 330 /* NVMe completion status code (generic) */
 331 #define NVME_CQE_SC_GEN_SUCCESS         0x0     /* Successful Completion */
 332 #define NVME_CQE_SC_GEN_INV_OPC         0x1     /* Invalid Command Opcode */
 333 #define NVME_CQE_SC_GEN_INV_FLD         0x2     /* Invalid Field in Command */
 334 #define NVME_CQE_SC_GEN_ID_CNFL         0x3     /* Command ID Conflict */
 335 #define NVME_CQE_SC_GEN_DATA_XFR_ERR    0x4     /* Data Transfer Error */
 336 #define NVME_CQE_SC_GEN_ABORT_PWRLOSS   0x5     /* Cmds Aborted / Pwr Loss */
 337 #define NVME_CQE_SC_GEN_INTERNAL_ERR    0x6     /* Internal Error */
 338 #define NVME_CQE_SC_GEN_ABORT_REQUEST   0x7     /* Command Abort Requested */
 339 #define NVME_CQE_SC_GEN_ABORT_SQ_DEL    0x8     /* Cmd Aborted / SQ deletion */
 340 #define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9     /* Cmd Aborted / Failed Fused */
 341 #define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa     /* Cmd Aborted / Missing Fusd */
 342 #define NVME_CQE_SC_GEN_INV_NS          0xb     /* Inval Namespace or Format */
 343 #define NVME_CQE_SC_GEN_CMD_SEQ_ERR     0xc     /* Command Sequence Error */
 344 #define NVME_CQE_SC_GEN_INV_SGL_LAST    0xd     /* Inval SGL Last Seg Desc */
 345 #define NVME_CQE_SC_GEN_INV_SGL_NUM     0xe     /* Inval Number of SGL Desc */
 346 #define NVME_CQE_SC_GEN_INV_DSGL_LEN    0xf     /* Data SGL Length Invalid */
 347 #define NVME_CQE_SC_GEN_INV_MSGL_LEN    0x10    /* Metadata SGL Length Inval */
 348 #define NVME_CQE_SC_GEN_INV_SGL_DESC    0x11    /* SGL Descriptor Type Inval */
 349 
 350 /* NVMe completion status code (generic NVM commands) */
 351 #define NVME_CQE_SC_GEN_NVM_LBA_RANGE   0x80    /* LBA Out Of Range */
 352 #define NVME_CQE_SC_GEN_NVM_CAP_EXC     0x81    /* Capacity Exceeded */
 353 #define NVME_CQE_SC_GEN_NVM_NS_NOTRDY   0x82    /* Namespace Not Ready */
 354 #define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT  0x83    /* Reservation Conflict */
 355 
 356 /* NVMe completion status code (command specific) */
 357 #define NVME_CQE_SC_SPC_INV_CQ          0x0     /* Completion Queue Invalid */
 358 #define NVME_CQE_SC_SPC_INV_QID         0x1     /* Invalid Queue Identifier */
 359 #define NVME_CQE_SC_SPC_MAX_QSZ_EXC     0x2     /* Max Queue Size Exceeded */
 360 #define NVME_CQE_SC_SPC_ABRT_CMD_EXC    0x3     /* Abort Cmd Limit Exceeded */
 361 #define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5     /* Async Event Request Limit */
 362 #define NVME_CQE_SC_SPC_INV_FW_SLOT     0x6     /* Invalid Firmware Slot */
 363 #define NVME_CQE_SC_SPC_INV_FW_IMG      0x7     /* Invalid Firmware Image */
 364 #define NVME_CQE_SC_SPC_INV_INT_VECT    0x8     /* Invalid Interrupt Vector */
 365 #define NVME_CQE_SC_SPC_INV_LOG_PAGE    0x9     /* Invalid Log Page */
 366 #define NVME_CQE_SC_SPC_INV_FORMAT      0xa     /* Invalid Format */
 367 #define NVME_CQE_SC_SPC_FW_RESET        0xb     /* FW Application Reset Reqd */
 368 #define NVME_CQE_SC_SPC_INV_Q_DEL       0xc     /* Invalid Queue Deletion */
 369 #define NVME_CQE_SC_SPC_FEAT_SAVE       0xd     /* Feature Id Not Saveable */
 370 #define NVME_CQE_SC_SPC_FEAT_CHG        0xe     /* Feature Not Changeable */
 371 #define NVME_CQE_SC_SPC_FEAT_NS_SPEC    0xf     /* Feature Not Namespace Spec */
 372 #define NVME_CQE_SC_SPC_FW_NSSR         0x10    /* FW Application NSSR Reqd */
 373 
 374 /* NVMe completion status code (NVM command specific */
 375 #define NVME_CQE_SC_SPC_NVM_CNFL_ATTR   0x80    /* Conflicting Attributes */
 376 #define NVME_CQE_SC_SPC_NVM_INV_PROT    0x81    /* Invalid Protection */
 377 #define NVME_CQE_SC_SPC_NVM_READONLY    0x82    /* Write to Read Only Range */
 378 
 379 /* NVMe completion status code (data / metadata integrity) */
 380 #define NVME_CQE_SC_INT_NVM_WRITE       0x80    /* Write Fault */
 381 #define NVME_CQE_SC_INT_NVM_READ        0x81    /* Unrecovered Read Error */
 382 #define NVME_CQE_SC_INT_NVM_GUARD       0x82    /* Guard Check Error */
 383 #define NVME_CQE_SC_INT_NVM_APPL_TAG    0x83    /* Application Tag Check Err */
 384 #define NVME_CQE_SC_INT_NVM_REF_TAG     0x84    /* Reference Tag Check Err */
 385 #define NVME_CQE_SC_INT_NVM_COMPARE     0x85    /* Compare Failure */
 386 #define NVME_CQE_SC_INT_NVM_ACCESS      0x86    /* Access Denied */
 387 
 388 /*
 389  * NVMe Asynchronous Event Request
 390  */
 391 #define NVME_ASYNC_TYPE_ERROR           0x0     /* Error Status */
 392 #define NVME_ASYNC_TYPE_HEALTH          0x1     /* SMART/Health Status */
 393 #define NVME_ASYNC_TYPE_VENDOR          0x7     /* vendor specific */
 394 
 395 #define NVME_ASYNC_ERROR_INV_SQ         0x0     /* Invalid Submission Queue */
 396 #define NVME_ASYNC_ERROR_INV_DBL        0x1     /* Invalid Doorbell Write */
 397 #define NVME_ASYNC_ERROR_DIAGFAIL       0x2     /* Diagnostic Failure */
 398 #define NVME_ASYNC_ERROR_PERSISTENT     0x3     /* Persistent Internal Error */
 399 #define NVME_ASYNC_ERROR_TRANSIENT      0x4     /* Transient Internal Error */
 400 #define NVME_ASYNC_ERROR_FW_LOAD        0x5     /* Firmware Image Load Error */
 401 
 402 #define NVME_ASYNC_HEALTH_RELIABILITY   0x0     /* Device Reliability */
 403 #define NVME_ASYNC_HEALTH_TEMPERATURE   0x1     /* Temp. Above Threshold */
 404 #define NVME_ASYNC_HEALTH_SPARE         0x2     /* Spare Below Threshold */
 405 
 406 typedef union {
 407         struct {
 408                 uint8_t ae_type:3;              /* Asynchronous Event Type */
 409                 uint8_t ae_rsvd1:5;
 410                 uint8_t ae_info;                /* Asynchronous Event Info */
 411                 uint8_t ae_logpage;             /* Associated Log Page */
 412                 uint8_t ae_rsvd2;
 413         } b;
 414         uint32_t r;
 415 } nvme_async_event_t;
 416 
 417 /*
 418  * NVMe Create Completion/Submission Queue
 419  */
 420 typedef union {
 421         struct {
 422                 uint16_t q_qid;                 /* Queue Identifier */
 423                 uint16_t q_qsize;               /* Queue Size */
 424         } b;
 425         uint32_t r;
 426 } nvme_create_queue_dw10_t;
 427 
 428 typedef union {
 429         struct {
 430                 uint16_t cq_pc:1;               /* Physically Contiguous */
 431                 uint16_t cq_ien:1;              /* Interrupts Enabled */
 432                 uint16_t cq_rsvd:14;
 433                 uint16_t cq_iv;                 /* Interrupt Vector */
 434         } b;
 435         uint32_t r;
 436 } nvme_create_cq_dw11_t;
 437 
 438 typedef union {
 439         struct {
 440                 uint16_t sq_pc:1;               /* Physically Contiguous */
 441                 uint16_t sq_qprio:2;            /* Queue Priority */
 442                 uint16_t sq_rsvd:13;
 443                 uint16_t sq_cqid;               /* Completion Queue ID */
 444         } b;
 445         uint32_t r;
 446 } nvme_create_sq_dw11_t;
 447 
 448 /*
 449  * NVMe Identify
 450  */
 451 
 452 /* NVMe Identify parameters (cdw10) */
 453 #define NVME_IDENTIFY_NSID      0x0     /* Identify Namespace */
 454 #define NVME_IDENTIFY_CTRL      0x1     /* Identify Controller */
 455 #define NVME_IDENTIFY_LIST      0x2     /* Identify List Namespaces */
 456 
 457 #define NVME_IDENTIFY_NSID_ALLOC_LIST   0x10    /* List Allocated NSID */
 458 #define NVME_IDENTIFY_NSID_ALLOC        0x11    /* Identify Allocated NSID */
 459 #define NVME_IDENTIFY_NSID_CTRL_LIST    0x12    /* List Controllers on NSID */
 460 #define NVME_IDENTIFY_CTRL_LIST         0x13    /* Controller List */
 461 #define NVME_IDENTIFY_PRIMARY_CAPS      0x14    /* Primary Controller Caps */
 462 
 463 /*
 464  * NVMe Abort Command
 465  */
 466 typedef union {
 467         struct {
 468                 uint16_t ac_sqid;       /* Submission Queue ID */
 469                 uint16_t ac_cid;        /* Command ID */
 470         } b;
 471         uint32_t r;
 472 } nvme_abort_cmd_t;
 473 
 474 
 475 /*
 476  * NVMe Get Log Page
 477  */
 478 typedef union {
 479         struct {
 480                 uint8_t lp_lid;         /* Log Page Identifier */
 481                 uint8_t lp_rsvd1;
 482                 uint16_t lp_numd:12;    /* Number of Dwords */
 483                 uint16_t lp_rsvd2:4;
 484         } b;
 485         uint32_t r;
 486 } nvme_getlogpage_t;
 487 
 488 
 489 #ifdef __cplusplus
 490 }
 491 #endif
 492 
 493 #pragma pack() /* pack(1) */
 494 
 495 #endif /* _NVME_REG_H */