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 */ 15 16 /* 17 * NVMe hardware interface 18 */ 19 20 #ifndef _NVME_REG_H 21 #define _NVME_REG_H 22 23 #pragma pack(1) 24 25 #ifdef __cplusplus 26 extern "C" { 27 #endif 28 29 30 /* 31 * NVMe constants 32 */ 33 #define NVME_MAX_ADMIN_QUEUE_LEN 4096 34 35 /* 36 * NVMe version 37 */ 38 typedef struct { 39 uint16_t v_minor; 40 uint16_t v_major; 41 } nvme_version_t; 42 43 #define NVME_VERSION_ATLEAST(v, maj, min) \ 44 (((v)->v_major) > (maj) || \ 45 ((v)->v_major == (maj) && (v)->v_minor >= (min))) 46 47 #define NVME_VERSION_HIGHER(v, maj, min) \ 48 (((v)->v_major) > (maj) || \ 49 ((v)->v_major == (maj) && (v)->v_minor > (min))) 50 51 /* 52 * NVMe registers and register fields 53 */ 54 #define NVME_REG_CAP 0x0 /* Controller Capabilities */ 55 #define NVME_REG_VS 0x8 /* Version */ 56 #define NVME_REG_INTMS 0xc /* Interrupt Mask Set */ 57 #define NVME_REG_INTMC 0x10 /* Interrupt Mask Clear */ 58 #define NVME_REG_CC 0x14 /* Controller Configuration */ 59 #define NVME_REG_CSTS 0x1c /* Controller Status */ 60 #define NVME_REG_NSSR 0x20 /* NVM Subsystem Reset */ 61 #define NVME_REG_AQA 0x24 /* Admin Queue Attributes */ 62 #define NVME_REG_ASQ 0x28 /* Admin Submission Queue */ 63 #define NVME_REG_ACQ 0x30 /* Admin Completion Qeueu */ 64 #define NVME_REG_SQTDBL(nvme, n) \ 65 (0x1000 + ((2 * (n)) * nvme->n_doorbell_stride)) 66 #define NVME_REG_CQHDBL(nvme, n) \ 67 (0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride)) 68 69 #define NVME_CAP_CSS_NVM 1 /* NVM Command Set */ 70 #define NVME_CAP_AMS_WRR 1 /* Weighted Round-Robin */ 71 72 /* CAP -- Controller Capabilities */ 73 typedef union { 74 struct { 75 uint16_t cap_mqes; /* Maximum Queue Entries Supported */ 76 uint8_t cap_cqr:1; /* Contiguous Queues Required */ 77 uint8_t cap_ams:2; /* Arbitration Mechanisms Supported */ 78 uint8_t cap_rsvd1:5; 79 uint8_t cap_to; /* Timeout */ 80 uint16_t cap_dstrd:4; /* Doorbell Stride */ 81 uint16_t cap_nssrs:1; /* NVM Subsystem Reset Supported */ 82 uint16_t cap_css:8; /* Command Sets Supported */ 83 uint16_t cap_rsvd2:3; 84 uint8_t cap_mpsmin:4; /* Memory Page Size Minimum */ 85 uint8_t cap_mpsmax:4; /* Memory Page Size Maximum */ 86 uint8_t cap_rsvd3; 87 } b; 88 uint64_t r; 89 } nvme_reg_cap_t; 90 91 /* VS -- Version */ 92 typedef union { 93 struct { 94 uint8_t vs_rsvd; 95 uint8_t vs_mnr; /* Minor Version Number */ 96 uint16_t vs_mjr; /* Major Version Number */ 97 } b; 98 uint32_t r; 99 } nvme_reg_vs_t; 100 101 /* CC -- Controller Configuration */ 102 #define NVME_CC_SHN_NORMAL 1 /* Normal Shutdown Notification */ 103 #define NVME_CC_SHN_ABRUPT 2 /* Abrupt Shutdown Notification */ 104 105 typedef union { 106 struct { 107 uint16_t cc_en:1; /* Enable */ 108 uint16_t cc_rsvd1:3; 109 uint16_t cc_css:3; /* I/O Command Set Selected */ 110 uint16_t cc_mps:4; /* Memory Page Size */ 111 uint16_t cc_ams:3; /* Arbitration Mechanism Selected */ 112 uint16_t cc_shn:2; /* Shutdown Notification */ 113 uint8_t cc_iosqes:4; /* I/O Submission Queue Entry Size */ 114 uint8_t cc_iocqes:4; /* I/O Completion Queue Entry Size */ 115 uint8_t cc_rsvd2; 116 } b; 117 uint32_t r; 118 } nvme_reg_cc_t; 119 120 /* CSTS -- Controller Status */ 121 #define NVME_CSTS_SHN_OCCURING 1 /* Shutdown Processing Occuring */ 122 #define NVME_CSTS_SHN_COMPLETE 2 /* Shutdown Processing Complete */ 123 124 typedef union { 125 struct { 126 uint32_t csts_rdy:1; /* Ready */ 127 uint32_t csts_cfs:1; /* Controller Fatal Status */ 128 uint32_t csts_shst:2; /* Shutdown Status */ 129 uint32_t csts_nssro:1; /* NVM Subsystem Reset Occured */ 130 uint32_t csts_rsvd:27; 131 } b; 132 uint32_t r; 133 } nvme_reg_csts_t; 134 135 /* NSSR -- NVM Subsystem Reset */ 136 #define NVME_NSSR_NSSRC 0x4e564d65 /* NSSR magic value */ 137 typedef uint32_t nvme_reg_nssr_t; 138 139 /* AQA -- Admin Queue Attributes */ 140 typedef union { 141 struct { 142 uint16_t aqa_asqs:12; /* Admin Submission Queue Size */ 143 uint16_t aqa_rsvd1:4; 144 uint16_t aqa_acqs:12; /* Admin Completion Queue Size */ 145 uint16_t aqa_rsvd2:4; 146 } b; 147 uint32_t r; 148 } nvme_reg_aqa_t; 149 150 /* 151 * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is 152 * probably a specification bug. The full 64bit regs are used as base address, 153 * and the lower bits must be zero to ensure alignment on the page size 154 * specified in CC.MPS. 155 */ 156 /* ASQ -- Admin Submission Queue Base Address */ 157 typedef uint64_t nvme_reg_asq_t; /* Admin Submission Queue Base */ 158 159 /* ACQ -- Admin Completion Queue Base Address */ 160 typedef uint64_t nvme_reg_acq_t; /* Admin Completion Queue Base */ 161 162 /* SQyTDBL -- Submission Queue y Tail Doorbell */ 163 typedef union { 164 struct { 165 uint16_t sqtdbl_sqt; /* Submission Queue Tail */ 166 uint16_t sqtdbl_rsvd; 167 } b; 168 uint32_t r; 169 } nvme_reg_sqtdbl_t; 170 171 /* CQyHDBL -- Completion Queue y Head Doorbell */ 172 typedef union { 173 struct { 174 uint16_t cqhdbl_cqh; /* Completion Queue Head */ 175 uint16_t cqhdbl_rsvd; 176 } b; 177 uint32_t r; 178 } nvme_reg_cqhdbl_t; 179 180 /* 181 * NVMe submission queue entries 182 */ 183 184 /* NVMe scatter/gather list descriptor */ 185 typedef struct { 186 uint64_t sgl_addr; /* Address */ 187 uint32_t sgl_len; /* Length */ 188 uint8_t sgl_rsvd[3]; 189 uint8_t sgl_zero:4; 190 uint8_t sgl_type:4; /* SGL descriptor type */ 191 } nvme_sgl_t; 192 193 /* NVMe SGL descriptor type */ 194 #define NVME_SGL_DATA_BLOCK 0 195 #define NVME_SGL_BIT_BUCKET 1 196 #define NVME_SGL_SEGMENT 2 197 #define NVME_SGL_LAST_SEGMENT 3 198 #define NVME_SGL_VENDOR 0xf 199 200 /* NVMe submission queue entry */ 201 typedef struct { 202 uint8_t sqe_opc; /* Opcode */ 203 uint8_t sqe_fuse:2; /* Fused Operation */ 204 uint8_t sqe_rsvd:5; 205 uint8_t sqe_psdt:1; /* PRP or SGL for Data Transfer */ 206 uint16_t sqe_cid; /* Command Identifier */ 207 uint32_t sqe_nsid; /* Namespace Identifier */ 208 uint64_t sqe_rsvd1; 209 union { 210 uint64_t m_ptr; /* Metadata Pointer */ 211 uint64_t m_sglp; /* Metadata SGL Segment Pointer */ 212 } sqe_m; 213 union { 214 uint64_t d_prp[2]; /* Physical Page Region Entries 1 & 2 */ 215 nvme_sgl_t d_sgl; /* SGL Entry 1 */ 216 } sqe_dptr; /* Data Pointer */ 217 uint32_t sqe_cdw10; /* Number of Dwords in Data Transfer */ 218 uint32_t sqe_cdw11; /* Number of Dwords in Metadata Xfer */ 219 uint32_t sqe_cdw12; 220 uint32_t sqe_cdw13; 221 uint32_t sqe_cdw14; 222 uint32_t sqe_cdw15; 223 } nvme_sqe_t; 224 225 /* NVMe admin command opcodes */ 226 #define NVME_OPC_DELETE_SQUEUE 0x0 227 #define NVME_OPC_CREATE_SQUEUE 0x1 228 #define NVME_OPC_GET_LOG_PAGE 0x2 229 #define NVME_OPC_DELETE_CQUEUE 0x4 230 #define NVME_OPC_CREATE_CQUEUE 0x5 231 #define NVME_OPC_IDENTIFY 0x6 232 #define NVME_OPC_ABORT 0x8 233 #define NVME_OPC_SET_FEATURES 0x9 234 #define NVME_OPC_GET_FEATURES 0xa 235 #define NVME_OPC_ASYNC_EVENT 0xc 236 #define NVME_OPC_FW_ACTIVATE 0x10 237 #define NVME_OPC_FW_IMAGE_LOAD 0x11 238 239 /* NVMe NVM command set specific admin command opcodes */ 240 #define NVME_OPC_NVM_FORMAT 0x80 241 #define NVME_OPC_NVM_SEC_SEND 0x81 242 #define NVME_OPC_NVM_SEC_RECV 0x82 243 244 /* NVMe NVM command opcodes */ 245 #define NVME_OPC_NVM_FLUSH 0x0 246 #define NVME_OPC_NVM_WRITE 0x1 247 #define NVME_OPC_NVM_READ 0x2 248 #define NVME_OPC_NVM_WRITE_UNC 0x4 249 #define NVME_OPC_NVM_COMPARE 0x5 250 #define NVME_OPC_NVM_WRITE_ZERO 0x8 251 #define NVME_OPC_NVM_DSET_MGMT 0x9 252 #define NVME_OPC_NVM_RESV_REG 0xd 253 #define NVME_OPC_NVM_RESV_REPRT 0xe 254 #define NVME_OPC_NVM_RESV_ACQ 0x11 255 #define NVME_OPC_NVM_RESV_REL 0x12 256 257 /* 258 * NVMe completion queue entry 259 */ 260 typedef struct { 261 uint16_t sf_p:1; /* Phase Tag */ 262 uint16_t sf_sc:8; /* Status Code */ 263 uint16_t sf_sct:3; /* Status Code Type */ 264 uint16_t sf_rsvd2:2; 265 uint16_t sf_m:1; /* More */ 266 uint16_t sf_dnr:1; /* Do Not Retry */ 267 } nvme_cqe_sf_t; 268 269 typedef struct { 270 uint32_t cqe_dw0; /* Command Specific */ 271 uint32_t cqe_rsvd1; 272 uint16_t cqe_sqhd; /* SQ Head Pointer */ 273 uint16_t cqe_sqid; /* SQ Identifier */ 274 uint16_t cqe_cid; /* Command Identifier */ 275 nvme_cqe_sf_t cqe_sf; /* Status Field */ 276 } nvme_cqe_t; 277 278 /* NVMe completion status code type */ 279 #define NVME_CQE_SCT_GENERIC 0 /* Generic Command Status */ 280 #define NVME_CQE_SCT_SPECIFIC 1 /* Command Specific Status */ 281 #define NVME_CQE_SCT_INTEGRITY 2 /* Media and Data Integrity Errors */ 282 #define NVME_CQE_SCT_VENDOR 7 /* Vendor Specific */ 283 284 /* NVMe completion status code (generic) */ 285 #define NVME_CQE_SC_GEN_SUCCESS 0x0 /* Successful Completion */ 286 #define NVME_CQE_SC_GEN_INV_OPC 0x1 /* Invalid Command Opcode */ 287 #define NVME_CQE_SC_GEN_INV_FLD 0x2 /* Invalid Field in Command */ 288 #define NVME_CQE_SC_GEN_ID_CNFL 0x3 /* Command ID Conflict */ 289 #define NVME_CQE_SC_GEN_DATA_XFR_ERR 0x4 /* Data Transfer Error */ 290 #define NVME_CQE_SC_GEN_ABORT_PWRLOSS 0x5 /* Cmds Aborted / Pwr Loss */ 291 #define NVME_CQE_SC_GEN_INTERNAL_ERR 0x6 /* Internal Error */ 292 #define NVME_CQE_SC_GEN_ABORT_REQUEST 0x7 /* Command Abort Requested */ 293 #define NVME_CQE_SC_GEN_ABORT_SQ_DEL 0x8 /* Cmd Aborted / SQ deletion */ 294 #define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9 /* Cmd Aborted / Failed Fused */ 295 #define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa /* Cmd Aborted / Missing Fusd */ 296 #define NVME_CQE_SC_GEN_INV_NS 0xb /* Inval Namespace or Format */ 297 #define NVME_CQE_SC_GEN_CMD_SEQ_ERR 0xc /* Command Sequence Error */ 298 #define NVME_CQE_SC_GEN_INV_SGL_LAST 0xd /* Inval SGL Last Seg Desc */ 299 #define NVME_CQE_SC_GEN_INV_SGL_NUM 0xe /* Inval Number of SGL Desc */ 300 #define NVME_CQE_SC_GEN_INV_DSGL_LEN 0xf /* Data SGL Length Invalid */ 301 #define NVME_CQE_SC_GEN_INV_MSGL_LEN 0x10 /* Metadata SGL Length Inval */ 302 #define NVME_CQE_SC_GEN_INV_SGL_DESC 0x11 /* SGL Descriptor Type Inval */ 303 304 /* NVMe completion status code (generic NVM commands) */ 305 #define NVME_CQE_SC_GEN_NVM_LBA_RANGE 0x80 /* LBA Out Of Range */ 306 #define NVME_CQE_SC_GEN_NVM_CAP_EXC 0x81 /* Capacity Exceeded */ 307 #define NVME_CQE_SC_GEN_NVM_NS_NOTRDY 0x82 /* Namespace Not Ready */ 308 #define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT 0x83 /* Reservation Conflict */ 309 310 /* NVMe completion status code (command specific) */ 311 #define NVME_CQE_SC_SPC_INV_CQ 0x0 /* Completion Queue Invalid */ 312 #define NVME_CQE_SC_SPC_INV_QID 0x1 /* Invalid Queue Identifier */ 313 #define NVME_CQE_SC_SPC_MAX_QSZ_EXC 0x2 /* Max Queue Size Exceeded */ 314 #define NVME_CQE_SC_SPC_ABRT_CMD_EXC 0x3 /* Abort Cmd Limit Exceeded */ 315 #define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5 /* Async Event Request Limit */ 316 #define NVME_CQE_SC_SPC_INV_FW_SLOT 0x6 /* Invalid Firmware Slot */ 317 #define NVME_CQE_SC_SPC_INV_FW_IMG 0x7 /* Invalid Firmware Image */ 318 #define NVME_CQE_SC_SPC_INV_INT_VECT 0x8 /* Invalid Interrupt Vector */ 319 #define NVME_CQE_SC_SPC_INV_LOG_PAGE 0x9 /* Invalid Log Page */ 320 #define NVME_CQE_SC_SPC_INV_FORMAT 0xa /* Invalid Format */ 321 #define NVME_CQE_SC_SPC_FW_RESET 0xb /* FW Application Reset Reqd */ 322 #define NVME_CQE_SC_SPC_INV_Q_DEL 0xc /* Invalid Queue Deletion */ 323 #define NVME_CQE_SC_SPC_FEAT_SAVE 0xd /* Feature Id Not Saveable */ 324 #define NVME_CQE_SC_SPC_FEAT_CHG 0xe /* Feature Not Changeable */ 325 #define NVME_CQE_SC_SPC_FEAT_NS_SPEC 0xf /* Feature Not Namespace Spec */ 326 #define NVME_CQE_SC_SPC_FW_NSSR 0x10 /* FW Application NSSR Reqd */ 327 328 /* NVMe completion status code (NVM command specific */ 329 #define NVME_CQE_SC_SPC_NVM_CNFL_ATTR 0x80 /* Conflicting Attributes */ 330 #define NVME_CQE_SC_SPC_NVM_INV_PROT 0x81 /* Invalid Protection */ 331 #define NVME_CQE_SC_SPC_NVM_READONLY 0x82 /* Write to Read Only Range */ 332 333 /* NVMe completion status code (data / metadata integrity) */ 334 #define NVME_CQE_SC_INT_NVM_WRITE 0x80 /* Write Fault */ 335 #define NVME_CQE_SC_INT_NVM_READ 0x81 /* Unrecovered Read Error */ 336 #define NVME_CQE_SC_INT_NVM_GUARD 0x82 /* Guard Check Error */ 337 #define NVME_CQE_SC_INT_NVM_APPL_TAG 0x83 /* Application Tag Check Err */ 338 #define NVME_CQE_SC_INT_NVM_REF_TAG 0x84 /* Reference Tag Check Err */ 339 #define NVME_CQE_SC_INT_NVM_COMPARE 0x85 /* Compare Failure */ 340 #define NVME_CQE_SC_INT_NVM_ACCESS 0x86 /* Access Denied */ 341 342 /* 343 * NVMe Asynchronous Event Request 344 */ 345 #define NVME_ASYNC_TYPE_ERROR 0x0 /* Error Status */ 346 #define NVME_ASYNC_TYPE_HEALTH 0x1 /* SMART/Health Status */ 347 #define NVME_ASYNC_TYPE_VENDOR 0x7 /* vendor specific */ 348 349 #define NVME_ASYNC_ERROR_INV_SQ 0x0 /* Invalid Submission Queue */ 350 #define NVME_ASYNC_ERROR_INV_DBL 0x1 /* Invalid Doorbell Write */ 351 #define NVME_ASYNC_ERROR_DIAGFAIL 0x2 /* Diagnostic Failure */ 352 #define NVME_ASYNC_ERROR_PERSISTENT 0x3 /* Persistent Internal Error */ 353 #define NVME_ASYNC_ERROR_TRANSIENT 0x4 /* Transient Internal Error */ 354 #define NVME_ASYNC_ERROR_FW_LOAD 0x5 /* Firmware Image Load Error */ 355 356 #define NVME_ASYNC_HEALTH_RELIABILITY 0x0 /* Device Reliability */ 357 #define NVME_ASYNC_HEALTH_TEMPERATURE 0x1 /* Temp. Above Threshold */ 358 #define NVME_ASYNC_HEALTH_SPARE 0x2 /* Spare Below Threshold */ 359 360 typedef union { 361 struct { 362 uint8_t ae_type:3; /* Asynchronous Event Type */ 363 uint8_t ae_rsvd1:5; 364 uint8_t ae_info; /* Asynchronous Event Info */ 365 uint8_t ae_logpage; /* Associated Log Page */ 366 uint8_t ae_rsvd2; 367 } b; 368 uint32_t r; 369 } nvme_async_event_t; 370 371 /* 372 * NVMe Create Completion/Submission Queue 373 */ 374 typedef union { 375 struct { 376 uint16_t q_qid; /* Queue Identifier */ 377 uint16_t q_qsize; /* Queue Size */ 378 } b; 379 uint32_t r; 380 } nvme_create_queue_dw10_t; 381 382 typedef union { 383 struct { 384 uint16_t cq_pc:1; /* Physically Contiguous */ 385 uint16_t cq_ien:1; /* Interrupts Enabled */ 386 uint16_t cq_rsvd:14; 387 uint16_t cq_iv; /* Interrupt Vector */ 388 } b; 389 uint32_t r; 390 } nvme_create_cq_dw11_t; 391 392 typedef union { 393 struct { 394 uint16_t sq_pc:1; /* Physically Contiguous */ 395 uint16_t sq_qprio:2; /* Queue Priority */ 396 uint16_t sq_rsvd:13; 397 uint16_t sq_cqid; /* Completion Queue ID */ 398 } b; 399 uint32_t r; 400 } nvme_create_sq_dw11_t; 401 402 /* 403 * NVMe Identify 404 */ 405 406 /* NVMe Identify parameters (cdw10) */ 407 #define NVME_IDENTIFY_NSID 0x0 /* Identify Namespace */ 408 #define NVME_IDENTIFY_CTRL 0x1 /* Identify Controller */ 409 #define NVME_IDENTIFY_LIST 0x2 /* Identify List Namespaces */ 410 411 #define NVME_IDENTIFY_BUFSIZE 4096 /* buffer size for Identify */ 412 413 /* NVMe Queue Entry Size bitfield */ 414 typedef struct { 415 uint8_t qes_min:4; /* minimum entry size */ 416 uint8_t qes_max:4; /* maximum entry size */ 417 } nvme_idctl_qes_t; 418 419 /* NVMe Power State Descriptor */ 420 typedef struct { 421 uint16_t psd_mp; /* Maximum Power */ 422 uint8_t psd_rsvd1; 423 uint8_t psd_mps:1; /* Max Power Scale (1.1) */ 424 uint8_t psd_nops:1; /* Non-Operational State (1.1) */ 425 uint8_t psd_rsvd2:6; 426 uint32_t psd_enlat; /* Entry Latency */ 427 uint32_t psd_exlat; /* Exit Latency */ 428 uint8_t psd_rrt:5; /* Relative Read Throughput */ 429 uint8_t psd_rsvd3:3; 430 uint8_t psd_rrl:5; /* Relative Read Latency */ 431 uint8_t psd_rsvd4:3; 432 uint8_t psd_rwt:5; /* Relative Write Throughput */ 433 uint8_t psd_rsvd5:3; 434 uint8_t psd_rwl:5; /* Relative Write Latency */ 435 uint8_t psd_rsvd6:3; 436 uint8_t psd_rsvd7[16]; 437 } nvme_idctl_psd_t; 438 439 /* NVMe Identify Controller Data Structure */ 440 typedef struct { 441 /* Controller Capabilities & Features */ 442 uint16_t id_vid; /* PCI vendor ID */ 443 uint16_t id_ssvid; /* PCI subsystem vendor ID */ 444 char id_serial[20]; /* Serial Number */ 445 char id_model[40]; /* Model Number */ 446 char id_fwrev[8]; /* Firmware Revision */ 447 uint8_t id_rab; /* Recommended Arbitration Burst */ 448 uint8_t id_oui[3]; /* vendor IEEE OUI */ 449 struct { /* Multi-Interface Capabilities */ 450 uint8_t m_multi_pci:1; /* HW has multiple PCIe interfaces */ 451 uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */ 452 uint8_t m_sr_iov:1; /* controller is SR-IOV virt fn (1.1) */ 453 uint8_t m_rsvd:5; 454 } id_mic; 455 uint8_t id_mdts; /* Maximum Data Transfer Size */ 456 uint16_t id_cntlid; /* Unique Controller Identifier (1.1) */ 457 uint8_t id_rsvd_cc[256 - 80]; 458 459 /* Admin Command Set Attributes */ 460 struct { /* Optional Admin Command Support */ 461 uint16_t oa_security:1; /* Security Send & Receive */ 462 uint16_t oa_format:1; /* Format NVM */ 463 uint16_t oa_firmare:1; /* Firmware Activate & Download */ 464 uint16_t oa_rsvd:13; 465 } id_oacs; 466 uint8_t id_acl; /* Abort Command Limit */ 467 uint8_t id_aerl; /* Asynchronous Event Request Limit */ 468 struct { /* Firmware Updates */ 469 uint8_t fw_readonly:1; /* Slot 1 is Read-Only */ 470 uint8_t fw_nslot:3; /* number of firmware slots */ 471 uint8_t fw_rsvd:4; 472 } id_frmw; 473 struct { /* Log Page Attributes */ 474 uint8_t lp_smart:1; /* SMART/Health information per NS */ 475 uint8_t lp_rsvd:7; 476 } id_lpa; 477 uint8_t id_elpe; /* Error Log Page Entries */ 478 uint8_t id_npss; /* Number of Power States */ 479 struct { /* Admin Vendor Specific Command Conf */ 480 uint8_t av_spec:1; /* use format from spec */ 481 uint8_t av_rsvd:7; 482 } id_avscc; 483 struct { /* Autonomous Power State Trans (1.1) */ 484 uint8_t ap_sup:1; /* APST supported (1.1) */ 485 uint8_t ap_rsvd:7; 486 } id_apsta; 487 uint8_t id_rsvd_ac[256 - 10]; 488 489 /* NVM Command Set Attributes */ 490 nvme_idctl_qes_t id_sqes; /* Submission Queue Entry Size */ 491 nvme_idctl_qes_t id_cqes; /* Completion Queue Entry Size */ 492 uint16_t id_rsvd_nc_1; 493 uint32_t id_nn; /* Number of Namespaces */ 494 struct { /* Optional NVM Command Support */ 495 uint16_t on_compare:1; /* Compare */ 496 uint16_t on_wr_unc:1; /* Write Uncorrectable */ 497 uint16_t on_dset_mgmt:1; /* Dataset Management */ 498 uint16_t on_wr_zero:1; /* Write Zeros (1.1) */ 499 uint16_t on_save:1; /* Save/Select in Get/Set Feat (1.1) */ 500 uint16_t on_reserve:1; /* Reservations (1.1) */ 501 uint16_t on_rsvd:10; 502 } id_oncs; 503 struct { /* Fused Operation Support */ 504 uint16_t f_cmp_wr:1; /* Compare and Write */ 505 uint16_t f_rsvd:15; 506 } id_fuses; 507 struct { /* Format NVM Attributes */ 508 uint8_t fn_format:1; /* Format applies to all NS */ 509 uint8_t fn_sec_erase:1; /* Secure Erase applies to all NS */ 510 uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */ 511 uint8_t fn_rsvd:5; 512 } id_fna; 513 struct { /* Volatile Write Cache */ 514 uint8_t vwc_present:1; /* Volatile Write Cache present */ 515 uint8_t rsvd:7; 516 } id_vwc; 517 uint16_t id_awun; /* Atomic Write Unit Normal */ 518 uint16_t id_awupf; /* Atomic Write Unit Power Fail */ 519 struct { /* NVM Vendor Specific Command Conf */ 520 uint8_t nv_spec:1; /* use format from spec */ 521 uint8_t nv_rsvd:7; 522 } id_nvscc; 523 uint8_t id_rsvd_nc_2; 524 uint16_t id_acwu; /* Atomic Compare & Write Unit (1.1) */ 525 uint16_t id_rsvd_nc_3; 526 struct { /* SGL Support (1.1) */ 527 uint16_t sgl_sup:1; /* SGL Supported in NVM cmds (1.1) */ 528 uint16_t sgl_rsvd1:15; 529 uint16_t sgl_bucket:1; /* SGL Bit Bucket supported (1.1) */ 530 uint16_t sgl_rsvd2:15; 531 } id_sgls; 532 uint8_t id_rsvd_nc_4[192 - 28]; 533 534 /* I/O Command Set Attributes */ 535 uint8_t id_rsvd_ioc[1344]; 536 537 /* Power State Descriptors */ 538 nvme_idctl_psd_t id_psd[32]; 539 540 /* Vendor Specific */ 541 uint8_t id_vs[1024]; 542 } nvme_identify_ctrl_t; 543 544 /* NVMe Identify Namespace LBA Format */ 545 typedef struct { 546 uint16_t lbaf_ms; /* Metadata Size */ 547 uint8_t lbaf_lbads; /* LBA Data Size */ 548 uint8_t lbaf_rp:2; /* Relative Performance */ 549 uint8_t lbaf_rsvd1:6; 550 } nvme_idns_lbaf_t; 551 552 /* NVMe Identify Namespace Data Structure */ 553 typedef struct { 554 uint64_t id_nsize; /* Namespace Size */ 555 uint64_t id_ncap; /* Namespace Capacity */ 556 uint64_t id_nuse; /* Namespace Utilization */ 557 struct { /* Namespace Features */ 558 uint8_t f_thin:1; /* Thin Provisioning */ 559 uint8_t f_rsvd:7; 560 } id_nsfeat; 561 uint8_t id_nlbaf; /* Number of LBA formats */ 562 struct { /* Formatted LBA size */ 563 uint8_t lba_format:4; /* LBA format */ 564 uint8_t lba_extlba:1; /* extended LBA (includes metadata) */ 565 uint8_t lba_rsvd:3; 566 } id_flbas; 567 struct { /* Metadata Capabilities */ 568 uint8_t mc_extlba:1; /* extended LBA transfers */ 569 uint8_t mc_separate:1; /* separate metadata transfers */ 570 uint8_t mc_rsvd:6; 571 } id_mc; 572 struct { /* Data Protection Capabilities */ 573 uint8_t dp_type1:1; /* Protection Information Type 1 */ 574 uint8_t dp_type2:1; /* Protection Information Type 2 */ 575 uint8_t dp_type3:1; /* Protection Information Type 3 */ 576 uint8_t dp_first:1; /* first 8 bytes of metadata */ 577 uint8_t dp_last:1; /* last 8 bytes of metadata */ 578 uint8_t dp_rsvd:3; 579 } id_dpc; 580 struct { /* Data Protection Settings */ 581 uint8_t dp_pinfo:3; /* Protection Information enabled */ 582 uint8_t dp_first:1; /* first 8 bytes of metadata */ 583 uint8_t dp_rsvd:4; 584 } id_dps; 585 struct { /* NS Multi-Path/Sharing Cap (1.1) */ 586 uint8_t nm_shared:1; /* NS is shared (1.1) */ 587 uint8_t nm_rsvd:7; 588 } id_nmic; 589 struct { /* Reservation Capabilities (1.1) */ 590 uint8_t rc_persist:1; /* Persist Through Power Loss (1.1) */ 591 uint8_t rc_wr_excl:1; /* Write Exclusive (1.1) */ 592 uint8_t rc_excl:1; /* Exclusive Access (1.1) */ 593 uint8_t rc_wr_excl_r:1; /* Wr Excl - Registrants Only (1.1) */ 594 uint8_t rc_excl_r:1; /* Excl Acc - Registrants Only (1.1) */ 595 uint8_t rc_wr_excl_a:1; /* Wr Excl - All Registrants (1.1) */ 596 uint8_t rc_excl_a:1; /* Excl Acc - All Registrants (1.1) */ 597 uint8_t rc_rsvd:1; 598 } id_rescap; 599 uint8_t id_rsvd1[120 - 32]; 600 uint8_t id_eui64[8]; /* IEEE Extended Unique Id (1.1) */ 601 nvme_idns_lbaf_t id_lbaf[16]; /* LBA Formats */ 602 603 uint8_t id_rsvd2[192]; 604 605 uint8_t id_vs[3712]; /* Vendor Specific */ 606 } nvme_identify_nsid_t; 607 608 609 /* 610 * NVMe Abort Command 611 */ 612 typedef union { 613 struct { 614 uint16_t ac_sqid; /* Submission Queue ID */ 615 uint16_t ac_cid; /* Command ID */ 616 } b; 617 uint32_t r; 618 } nvme_abort_cmd_t; 619 620 621 /* 622 * NVMe Get / Set Features 623 */ 624 #define NVME_FEAT_ARBITRATION 0x1 /* Command Arbitration */ 625 #define NVME_FEAT_POWER_MGMT 0x2 /* Power Management */ 626 #define NVME_FEAT_LBA_RANGE 0x3 /* LBA Range Type */ 627 #define NVME_FEAT_TEMPERATURE 0x4 /* Temperature Threshold */ 628 #define NVME_FEAT_ERROR 0x5 /* Error Recovery */ 629 #define NVME_FEAT_WRITE_CACHE 0x6 /* Volatile Write Cache */ 630 #define NVME_FEAT_NQUEUES 0x7 /* Number of Queues */ 631 #define NVME_FEAT_INTR_COAL 0x8 /* Interrupt Coalescing */ 632 #define NVME_FEAT_INTR_VECT 0x9 /* Interrupt Vector Configuration */ 633 #define NVME_FEAT_WRITE_ATOM 0xa /* Write Atomicity */ 634 #define NVME_FEAT_ASYNC_EVENT 0xb /* Asynchronous Event Configuration */ 635 #define NVME_FEAT_AUTO_PST 0xc /* Autonomous Power State Transition */ 636 /* (1.1) */ 637 638 #define NVME_FEAT_PROGRESS 0x80 /* Software Progress Marker */ 639 640 /* Arbitration Feature */ 641 typedef struct { 642 uint8_t arb_ab:3; /* Arbitration Burst */ 643 uint8_t arb_rsvd:5; 644 uint8_t arb_lpw; /* Low Priority Weight */ 645 uint8_t arb_mpw; /* Medium Priority Weight */ 646 uint8_t arb_hpw; /* High Priority Weight */ 647 } nvme_arbitration_dw11_t; 648 649 /* LBA Range Type Feature */ 650 typedef struct { 651 uint32_t lr_num:6; /* Number of LBA ranges */ 652 uint32_t lr_rsvd:26; 653 } nvme_lba_range_type_dw11_t; 654 655 typedef struct { 656 uint8_t lr_type; /* Type */ 657 struct { /* Attributes */ 658 uint8_t lr_write:1; /* may be overwritten */ 659 uint8_t lr_hidden:1; /* hidden from OS/EFI/BIOS */ 660 uint8_t lr_rsvd1:6; 661 } lr_attr; 662 uint8_t lr_rsvd2[14]; 663 uint64_t lr_slba; /* Starting LBA */ 664 uint64_t lr_nlb; /* Number of Logical Blocks */ 665 uint8_t lr_guid[16]; /* Unique Identifier */ 666 uint8_t lr_rsvd3[16]; 667 } nvme_lba_range_type_t; 668 669 /* Volatile Write Cache Feature */ 670 typedef union { 671 struct { 672 uint32_t wc_wce:1; /* Volatile Write Cache Enable */ 673 uint32_t wc_rsvd:31; 674 } b; 675 uint32_t r; 676 } nvme_write_cache_t; 677 678 /* Number of Queues */ 679 typedef union { 680 struct { 681 uint16_t nq_nsq; /* Number of Submission Queues */ 682 uint16_t nq_ncq; /* Number of Completion Queues */ 683 } b; 684 uint32_t r; 685 } nvme_nqueue_t; 686 687 688 /* 689 * NVMe Get Log Page 690 */ 691 #define NVME_LOGPAGE_ERROR 0x1 /* Error Information */ 692 #define NVME_LOGPAGE_HEALTH 0x2 /* SMART/Health Information */ 693 #define NVME_LOGPAGE_FWSLOT 0x3 /* Firmware Slot Information */ 694 695 typedef union { 696 struct { 697 uint8_t lp_lid; /* Log Page Identifier */ 698 uint8_t lp_rsvd1; 699 uint16_t lp_numd:12; /* Number of Dwords */ 700 uint16_t lp_rsvd2:4; 701 } b; 702 uint32_t r; 703 } nvme_getlogpage_t; 704 705 typedef struct { 706 uint64_t el_count; /* Error Count */ 707 uint16_t el_sqid; /* Submission Queue ID */ 708 uint16_t el_cid; /* Command ID */ 709 nvme_cqe_sf_t el_sf; /* Status Field */ 710 uint8_t el_byte; /* Parameter Error Location byte */ 711 uint8_t el_bit:3; /* Parameter Error Location bit */ 712 uint8_t el_rsvd1:5; 713 uint64_t el_lba; /* Logical Block Address */ 714 uint32_t el_nsid; /* Namespace ID */ 715 uint8_t el_vendor; /* Vendor Specific Information avail */ 716 uint8_t el_rsvd2[64 - 29]; 717 } nvme_error_log_entry_t; 718 719 typedef struct { 720 uint64_t lo; 721 uint64_t hi; 722 } nvme_uint128_t; 723 724 typedef struct { 725 uint8_t hl_crit_warn; /* Critical Warning */ 726 uint16_t hl_temp; /* Temperature */ 727 uint8_t hl_avail_spare; /* Available Spare */ 728 uint8_t hl_avail_spare_thr; /* Available Spare Threshold */ 729 uint8_t hl_used; /* Percentage Used */ 730 uint8_t hl_rsvd1[32 - 6]; 731 nvme_uint128_t hl_data_read; /* Data Units Read */ 732 nvme_uint128_t hl_data_write; /* Data Units Written */ 733 nvme_uint128_t hl_host_read; /* Host Read Commands */ 734 nvme_uint128_t hl_host_write; /* Host Write Commands */ 735 nvme_uint128_t hl_ctrl_busy; /* Controller Busy Time */ 736 nvme_uint128_t hl_power_cycles; /* Power Cycles */ 737 nvme_uint128_t hl_power_on_hours; /* Power On Hours */ 738 nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */ 739 nvme_uint128_t hl_media_errors; /* Media Errors */ 740 nvme_uint128_t hl_errors_logged; /* Number of errors logged */ 741 uint8_t hl_rsvd2[512 - 192]; 742 } nvme_health_log_t; 743 744 typedef struct { 745 uint8_t fw_afi:3; /* Active Firmware Slot */ 746 uint8_t fw_rsvd1:5; 747 uint8_t fw_rsvd2[7]; 748 char fw_frs[7][8]; /* Firmware Revision / Slot */ 749 uint8_t fw_rsvd3[512 - 64]; 750 } nvme_fwslot_log_t; 751 752 #ifdef __cplusplus 753 } 754 #endif 755 756 #pragma pack() /* pack(1) */ 757 758 #endif /* _NVME_REG_H */ 759