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. 14 * Copyright (c) 2018, Joyent, Inc. 15 * Copyright 2019 Western Digital Corporation 16 */ 17 18 #ifndef _SYS_NVME_H 19 #define _SYS_NVME_H 20 21 #include <sys/types.h> 22 23 #ifdef _KERNEL 24 #include <sys/types32.h> 25 #else 26 #include <stdint.h> 27 #endif 28 29 /* 30 * Declarations used for communication between nvmeadm(1M) and nvme(7D) 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 /* 38 * NVMe ioctl definitions 39 */ 40 41 #define NVME_IOC (('N' << 24) | ('V' << 16) | ('M' << 8)) 42 #define NVME_IOC_IDENTIFY_CTRL (NVME_IOC | 1) 43 #define NVME_IOC_IDENTIFY_NSID (NVME_IOC | 2) 44 #define NVME_IOC_CAPABILITIES (NVME_IOC | 3) 45 #define NVME_IOC_GET_LOGPAGE (NVME_IOC | 4) 46 #define NVME_IOC_GET_FEATURES (NVME_IOC | 5) 47 #define NVME_IOC_INTR_CNT (NVME_IOC | 6) 48 #define NVME_IOC_VERSION (NVME_IOC | 7) 49 #define NVME_IOC_FORMAT (NVME_IOC | 8) 50 #define NVME_IOC_DETACH (NVME_IOC | 9) 51 #define NVME_IOC_ATTACH (NVME_IOC | 10) 52 #define NVME_IOC_FIRMWARE_DOWNLOAD (NVME_IOC | 11) 53 #define NVME_IOC_FIRMWARE_COMMIT (NVME_IOC | 12) 54 #define NVME_IOC_MAX NVME_IOC_FIRMWARE_COMMIT 55 56 #define IS_NVME_IOC(x) ((x) > NVME_IOC && (x) <= NVME_IOC_MAX) 57 #define NVME_IOC_CMD(x) ((x) & 0xff) 58 59 typedef struct { 60 size_t n_len; 61 uintptr_t n_buf; 62 uint64_t n_arg; 63 } nvme_ioctl_t; 64 65 #ifdef _KERNEL 66 typedef struct { 67 size32_t n_len; 68 uintptr32_t n_buf; 69 uint64_t n_arg; 70 } nvme_ioctl32_t; 71 #endif 72 73 /* 74 * NVMe capabilities 75 */ 76 typedef struct { 77 uint32_t mpsmax; /* Memory Page Size Maximum */ 78 uint32_t mpsmin; /* Memory Page Size Minimum */ 79 } nvme_capabilities_t; 80 81 /* 82 * NVMe version 83 */ 84 typedef struct { 85 uint16_t v_minor; 86 uint16_t v_major; 87 } nvme_version_t; 88 89 #define NVME_VERSION_ATLEAST(v, maj, min) \ 90 (((v)->v_major) > (maj) || \ 91 ((v)->v_major == (maj) && (v)->v_minor >= (min))) 92 93 #define NVME_VERSION_HIGHER(v, maj, min) \ 94 (((v)->v_major) > (maj) || \ 95 ((v)->v_major == (maj) && (v)->v_minor > (min))) 96 97 98 #pragma pack(1) 99 100 /* 101 * NVMe Identify data structures 102 */ 103 104 #define NVME_IDENTIFY_BUFSIZE 4096 /* buffer size for Identify */ 105 106 /* NVMe Queue Entry Size bitfield */ 107 typedef struct { 108 uint8_t qes_min:4; /* minimum entry size */ 109 uint8_t qes_max:4; /* maximum entry size */ 110 } nvme_idctl_qes_t; 111 112 /* NVMe Power State Descriptor */ 113 typedef struct { 114 uint16_t psd_mp; /* Maximum Power */ 115 uint8_t psd_rsvd1; 116 uint8_t psd_mps:1; /* Max Power Scale (1.1) */ 117 uint8_t psd_nops:1; /* Non-Operational State (1.1) */ 118 uint8_t psd_rsvd2:6; 119 uint32_t psd_enlat; /* Entry Latency */ 120 uint32_t psd_exlat; /* Exit Latency */ 121 uint8_t psd_rrt:5; /* Relative Read Throughput */ 122 uint8_t psd_rsvd3:3; 123 uint8_t psd_rrl:5; /* Relative Read Latency */ 124 uint8_t psd_rsvd4:3; 125 uint8_t psd_rwt:5; /* Relative Write Throughput */ 126 uint8_t psd_rsvd5:3; 127 uint8_t psd_rwl:5; /* Relative Write Latency */ 128 uint8_t psd_rsvd6:3; 129 uint16_t psd_idlp; /* Idle Power (1.2) */ 130 uint8_t psd_rsvd7:6; 131 uint8_t psd_ips:2; /* Idle Power Scale (1.2) */ 132 uint8_t psd_rsvd8; 133 uint16_t psd_actp; /* Active Power (1.2) */ 134 uint8_t psd_apw:3; /* Active Power Workload (1.2) */ 135 uint8_t psd_rsvd9:3; 136 uint8_t psd_aps:2; /* Active Power Scale */ 137 uint8_t psd_rsvd10[9]; 138 } nvme_idctl_psd_t; 139 140 /* NVMe Identify Controller Data Structure */ 141 typedef struct { 142 /* Controller Capabilities & Features */ 143 uint16_t id_vid; /* PCI vendor ID */ 144 uint16_t id_ssvid; /* PCI subsystem vendor ID */ 145 char id_serial[20]; /* Serial Number */ 146 char id_model[40]; /* Model Number */ 147 char id_fwrev[8]; /* Firmware Revision */ 148 uint8_t id_rab; /* Recommended Arbitration Burst */ 149 uint8_t id_oui[3]; /* vendor IEEE OUI */ 150 struct { /* Multi-Interface Capabilities */ 151 uint8_t m_multi_pci:1; /* HW has multiple PCIe interfaces */ 152 uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */ 153 uint8_t m_sr_iov:1; /* controller is SR-IOV virt fn (1.1) */ 154 uint8_t m_rsvd:5; 155 } id_mic; 156 uint8_t id_mdts; /* Maximum Data Transfer Size */ 157 uint16_t id_cntlid; /* Unique Controller Identifier (1.1) */ 158 /* Added in NVMe 1.2 */ 159 uint32_t id_ver; /* Version */ 160 uint32_t id_rtd3r; /* RTD3 Resume Latency */ 161 uint32_t id_rtd3e; /* RTD3 Entry Latency */ 162 uint32_t id_oaes; /* Optional Asynchronous Events */ 163 /* Added in NVMe 1.3 */ 164 uint32_t id_ctratt; /* Controller Attributes */ 165 uint8_t id_rsvd_cc[12]; 166 uint8_t id_frguid[16]; /* FRU GUID */ 167 uint8_t id_rsvd2_cc[240 - 128]; 168 uint8_t id_rsvd_nvmemi[255 - 240]; 169 uint8_t id_mec; /* Management Endpiont Capabilities */ 170 171 /* Admin Command Set Attributes */ 172 struct { /* Optional Admin Command Support */ 173 uint16_t oa_security:1; /* Security Send & Receive */ 174 uint16_t oa_format:1; /* Format NVM */ 175 uint16_t oa_firmware:1; /* Firmware Activate & Download */ 176 uint16_t oa_rsvd:13; 177 } id_oacs; 178 uint8_t id_acl; /* Abort Command Limit */ 179 uint8_t id_aerl; /* Asynchronous Event Request Limit */ 180 struct { /* Firmware Updates */ 181 uint8_t fw_readonly:1; /* Slot 1 is Read-Only */ 182 uint8_t fw_nslot:3; /* number of firmware slots */ 183 uint8_t fw_rsvd:4; 184 } id_frmw; 185 struct { /* Log Page Attributes */ 186 uint8_t lp_smart:1; /* SMART/Health information per NS */ 187 uint8_t lp_rsvd:7; 188 } id_lpa; 189 uint8_t id_elpe; /* Error Log Page Entries */ 190 uint8_t id_npss; /* Number of Power States */ 191 struct { /* Admin Vendor Specific Command Conf */ 192 uint8_t av_spec:1; /* use format from spec */ 193 uint8_t av_rsvd:7; 194 } id_avscc; 195 struct { /* Autonomous Power State Trans (1.1) */ 196 uint8_t ap_sup:1; /* APST supported (1.1) */ 197 uint8_t ap_rsvd:7; 198 } id_apsta; 199 /* Added in NVMe 1.2 */ 200 uint16_t ap_wctemp; /* Warning Composite Temperature */ 201 uint16_t ap_cctemp; /* Critical Composite Temperature */ 202 uint16_t ap_mtfa; /* Maximum Firmware Activation Time */ 203 uint32_t ap_hmpre; /* Host Memory Buffer Preferred Size */ 204 uint32_t ap_hmmin; /* Host Memory Buffer Min Size */ 205 uint8_t ap_tnvmcap[16]; /* Total NVM Capacity in Bytes */ 206 uint8_t ap_unvmcap[16]; /* Unallocated NVM Capacity */ 207 uint32_t ap_rpmbs; /* Replay Protected Memory Block */ 208 /* Added in NVMe 1.3 */ 209 uint16_t ap_edstt; /* Extended Device Self-test time */ 210 uint8_t ap_dsto; /* Device Self-test Options */ 211 uint8_t ap_fwug; /* Firmware Update Granularity */ 212 uint16_t ap_kas; /* Keep Alive Support */ 213 uint16_t ap_hctma; /* Host Thermal Management */ 214 uint16_t ap_mntmt; /* Minimum Thermal Temperature */ 215 uint16_t ap_mxtmt; /* Maximum Thermal Temperature */ 216 uint32_t ap_sanitize; /* Sanitize Caps */ 217 uint8_t id_rsvd_ac[512 - 332]; 218 219 /* NVM Command Set Attributes */ 220 nvme_idctl_qes_t id_sqes; /* Submission Queue Entry Size */ 221 nvme_idctl_qes_t id_cqes; /* Completion Queue Entry Size */ 222 uint16_t id_maxcmd; /* Max Outstanding Commands (1.3) */ 223 uint32_t id_nn; /* Number of Namespaces */ 224 struct { /* Optional NVM Command Support */ 225 uint16_t on_compare:1; /* Compare */ 226 uint16_t on_wr_unc:1; /* Write Uncorrectable */ 227 uint16_t on_dset_mgmt:1; /* Dataset Management */ 228 uint16_t on_wr_zero:1; /* Write Zeros (1.1) */ 229 uint16_t on_save:1; /* Save/Select in Get/Set Feat (1.1) */ 230 uint16_t on_reserve:1; /* Reservations (1.1) */ 231 uint16_t on_rsvd:10; 232 } id_oncs; 233 struct { /* Fused Operation Support */ 234 uint16_t f_cmp_wr:1; /* Compare and Write */ 235 uint16_t f_rsvd:15; 236 } id_fuses; 237 struct { /* Format NVM Attributes */ 238 uint8_t fn_format:1; /* Format applies to all NS */ 239 uint8_t fn_sec_erase:1; /* Secure Erase applies to all NS */ 240 uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */ 241 uint8_t fn_rsvd:5; 242 } id_fna; 243 struct { /* Volatile Write Cache */ 244 uint8_t vwc_present:1; /* Volatile Write Cache present */ 245 uint8_t rsvd:7; 246 } id_vwc; 247 uint16_t id_awun; /* Atomic Write Unit Normal */ 248 uint16_t id_awupf; /* Atomic Write Unit Power Fail */ 249 struct { /* NVM Vendor Specific Command Conf */ 250 uint8_t nv_spec:1; /* use format from spec */ 251 uint8_t nv_rsvd:7; 252 } id_nvscc; 253 uint8_t id_rsvd_nc_2; 254 uint16_t id_acwu; /* Atomic Compare & Write Unit (1.1) */ 255 uint16_t id_rsvd_nc_3; 256 struct { /* SGL Support (1.1) */ 257 uint16_t sgl_sup:1; /* SGL Supported in NVM cmds (1.1) */ 258 uint16_t sgl_rsvd1:15; 259 uint16_t sgl_bucket:1; /* SGL Bit Bucket supported (1.1) */ 260 uint16_t sgl_rsvd2:15; 261 } id_sgls; 262 uint8_t id_rsvd_nc_4[768 - 540]; 263 264 /* I/O Command Set Attributes */ 265 uint8_t id_subnqn[1024 - 768]; /* Subsystem Qualified Name (1.2.1+) */ 266 uint8_t id_rsvd_ioc[1792 - 1024]; 267 uint8_t id_nvmof[2048 - 1792]; /* NVMe over Fabrics */ 268 269 /* Power State Descriptors */ 270 nvme_idctl_psd_t id_psd[32]; 271 272 /* Vendor Specific */ 273 uint8_t id_vs[1024]; 274 } nvme_identify_ctrl_t; 275 276 /* NVMe Identify Namespace LBA Format */ 277 typedef struct { 278 uint16_t lbaf_ms; /* Metadata Size */ 279 uint8_t lbaf_lbads; /* LBA Data Size */ 280 uint8_t lbaf_rp:2; /* Relative Performance */ 281 uint8_t lbaf_rsvd1:6; 282 } nvme_idns_lbaf_t; 283 284 /* NVMe Identify Namespace Data Structure */ 285 typedef struct { 286 uint64_t id_nsize; /* Namespace Size */ 287 uint64_t id_ncap; /* Namespace Capacity */ 288 uint64_t id_nuse; /* Namespace Utilization */ 289 struct { /* Namespace Features */ 290 uint8_t f_thin:1; /* Thin Provisioning */ 291 uint8_t f_rsvd:7; 292 } id_nsfeat; 293 uint8_t id_nlbaf; /* Number of LBA formats */ 294 struct { /* Formatted LBA size */ 295 uint8_t lba_format:4; /* LBA format */ 296 uint8_t lba_extlba:1; /* extended LBA (includes metadata) */ 297 uint8_t lba_rsvd:3; 298 } id_flbas; 299 struct { /* Metadata Capabilities */ 300 uint8_t mc_extlba:1; /* extended LBA transfers */ 301 uint8_t mc_separate:1; /* separate metadata transfers */ 302 uint8_t mc_rsvd:6; 303 } id_mc; 304 struct { /* Data Protection Capabilities */ 305 uint8_t dp_type1:1; /* Protection Information Type 1 */ 306 uint8_t dp_type2:1; /* Protection Information Type 2 */ 307 uint8_t dp_type3:1; /* Protection Information Type 3 */ 308 uint8_t dp_first:1; /* first 8 bytes of metadata */ 309 uint8_t dp_last:1; /* last 8 bytes of metadata */ 310 uint8_t dp_rsvd:3; 311 } id_dpc; 312 struct { /* Data Protection Settings */ 313 uint8_t dp_pinfo:3; /* Protection Information enabled */ 314 uint8_t dp_first:1; /* first 8 bytes of metadata */ 315 uint8_t dp_rsvd:4; 316 } id_dps; 317 struct { /* NS Multi-Path/Sharing Cap (1.1) */ 318 uint8_t nm_shared:1; /* NS is shared (1.1) */ 319 uint8_t nm_rsvd:7; 320 } id_nmic; 321 struct { /* Reservation Capabilities (1.1) */ 322 uint8_t rc_persist:1; /* Persist Through Power Loss (1.1) */ 323 uint8_t rc_wr_excl:1; /* Write Exclusive (1.1) */ 324 uint8_t rc_excl:1; /* Exclusive Access (1.1) */ 325 uint8_t rc_wr_excl_r:1; /* Wr Excl - Registrants Only (1.1) */ 326 uint8_t rc_excl_r:1; /* Excl Acc - Registrants Only (1.1) */ 327 uint8_t rc_wr_excl_a:1; /* Wr Excl - All Registrants (1.1) */ 328 uint8_t rc_excl_a:1; /* Excl Acc - All Registrants (1.1) */ 329 uint8_t rc_rsvd:1; 330 } id_rescap; 331 uint8_t id_fpi; /* Format Progress Indicator (1.2) */ 332 uint8_t id_dfleat; /* Deallocate Log. Block (1.3) */ 333 uint16_t id_nawun; /* Atomic Write Unit Normal (1.2) */ 334 uint16_t id_nawupf; /* Atomic Write Unit Power Fail (1.2) */ 335 uint16_t id_nacwu; /* Atomic Compare & Write Unit (1.2) */ 336 uint16_t id_nabsn; /* Atomic Boundary Size Normal (1.2) */ 337 uint16_t id_nbao; /* Atomic Boundary Offset (1.2) */ 338 uint16_t id_nabspf; /* Atomic Boundary Size Fail (1.2) */ 339 uint16_t id_noiob; /* Optimal I/O Bondary (1.3) */ 340 uint8_t id_nvmcap[16]; /* NVM Capacity */ 341 uint8_t id_rsvd1[104 - 64]; 342 uint8_t id_nguid[16]; /* Namespace GUID (1.2) */ 343 uint8_t id_eui64[8]; /* IEEE Extended Unique Id (1.1) */ 344 nvme_idns_lbaf_t id_lbaf[16]; /* LBA Formats */ 345 346 uint8_t id_rsvd2[384 - 192]; 347 348 uint8_t id_vs[4096 - 384]; /* Vendor Specific */ 349 } nvme_identify_nsid_t; 350 351 /* NVMe Identify Primary Controller Capabilities */ 352 typedef struct { 353 uint16_t nipc_cntlid; /* Controller ID */ 354 uint16_t nipc_portid; /* Port Identifier */ 355 uint8_t nipc_crt; /* Controller Resource Types */ 356 uint8_t nipc_rsvd0[32 - 5]; 357 uint32_t nipc_vqfrt; /* VQ Resources Flexible Total */ 358 uint32_t nipc_vqrfa; /* VQ Resources Flexible Assigned */ 359 uint16_t nipc_vqrfap; /* VQ Resources to Primary */ 360 uint16_t nipc_vqprt; /* VQ Resources Private Total */ 361 uint16_t nipc_vqfrsm; /* VQ Resources Secondary Max */ 362 uint16_t nipc_vqgran; /* VQ Flexible Resource Gran */ 363 uint8_t nipc_rvsd1[64 - 48]; 364 uint32_t nipc_vifrt; /* VI Flexible total */ 365 uint32_t nipc_virfa; /* VI Flexible Assigned */ 366 uint16_t nipc_virfap; /* VI Flexible Allocatd to Primary */ 367 uint16_t nipc_viprt; /* VI Resources Private Total */ 368 uint16_t nipc_vifrsm; /* VI Resources Secondary Max */ 369 uint16_t nipc_vigran; /* VI Flexible Granularity */ 370 uint8_t nipc_rsvd2[4096 - 80]; 371 } nvme_identify_primary_caps_t; 372 373 /* 374 * NVMe completion queue entry status field 375 */ 376 typedef struct { 377 uint16_t sf_p:1; /* Phase Tag */ 378 uint16_t sf_sc:8; /* Status Code */ 379 uint16_t sf_sct:3; /* Status Code Type */ 380 uint16_t sf_rsvd2:2; 381 uint16_t sf_m:1; /* More */ 382 uint16_t sf_dnr:1; /* Do Not Retry */ 383 } nvme_cqe_sf_t; 384 385 386 /* 387 * NVMe Get Log Page 388 */ 389 #define NVME_LOGPAGE_ERROR 0x1 /* Error Information */ 390 #define NVME_LOGPAGE_HEALTH 0x2 /* SMART/Health Information */ 391 #define NVME_LOGPAGE_FWSLOT 0x3 /* Firmware Slot Information */ 392 393 typedef struct { 394 uint64_t el_count; /* Error Count */ 395 uint16_t el_sqid; /* Submission Queue ID */ 396 uint16_t el_cid; /* Command ID */ 397 nvme_cqe_sf_t el_sf; /* Status Field */ 398 uint8_t el_byte; /* Parameter Error Location byte */ 399 uint8_t el_bit:3; /* Parameter Error Location bit */ 400 uint8_t el_rsvd1:5; 401 uint64_t el_lba; /* Logical Block Address */ 402 uint32_t el_nsid; /* Namespace ID */ 403 uint8_t el_vendor; /* Vendor Specific Information avail */ 404 uint8_t el_rsvd2[64 - 29]; 405 } nvme_error_log_entry_t; 406 407 typedef struct { 408 uint64_t lo; 409 uint64_t hi; 410 } nvme_uint128_t; 411 412 typedef struct { 413 struct { /* Critical Warning */ 414 uint8_t cw_avail:1; /* available space too low */ 415 uint8_t cw_temp:1; /* temperature too high */ 416 uint8_t cw_reliab:1; /* degraded reliability */ 417 uint8_t cw_readonly:1; /* media is read-only */ 418 uint8_t cw_volatile:1; /* volatile memory backup failed */ 419 uint8_t cw_rsvd:3; 420 } hl_crit_warn; 421 uint16_t hl_temp; /* Temperature */ 422 uint8_t hl_avail_spare; /* Available Spare */ 423 uint8_t hl_avail_spare_thr; /* Available Spare Threshold */ 424 uint8_t hl_used; /* Percentage Used */ 425 uint8_t hl_rsvd1[32 - 6]; 426 nvme_uint128_t hl_data_read; /* Data Units Read */ 427 nvme_uint128_t hl_data_write; /* Data Units Written */ 428 nvme_uint128_t hl_host_read; /* Host Read Commands */ 429 nvme_uint128_t hl_host_write; /* Host Write Commands */ 430 nvme_uint128_t hl_ctrl_busy; /* Controller Busy Time */ 431 nvme_uint128_t hl_power_cycles; /* Power Cycles */ 432 nvme_uint128_t hl_power_on_hours; /* Power On Hours */ 433 nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */ 434 nvme_uint128_t hl_media_errors; /* Media Errors */ 435 nvme_uint128_t hl_errors_logged; /* Number of errors logged */ 436 uint8_t hl_rsvd2[512 - 192]; 437 } nvme_health_log_t; 438 439 typedef struct { 440 uint8_t fw_afi:3; /* Active Firmware Slot */ 441 uint8_t fw_rsvd1:1; 442 uint8_t fw_next:3; /* Next Active Firmware Slot */ 443 uint8_t fw_rsvd2:1; 444 uint8_t fw_rsvd3[7]; 445 char fw_frs[7][8]; /* Firmware Revision / Slot */ 446 uint8_t fw_rsvd4[512 - 64]; 447 } nvme_fwslot_log_t; 448 449 450 /* 451 * NVMe Format NVM 452 */ 453 #define NVME_FRMT_SES_NONE 0 454 #define NVME_FRMT_SES_USER 1 455 #define NVME_FRMT_SES_CRYPTO 2 456 #define NVME_FRMT_MAX_SES 2 457 458 #define NVME_FRMT_MAX_LBAF 15 459 460 typedef union { 461 struct { 462 uint32_t fm_lbaf:4; /* LBA Format */ 463 uint32_t fm_ms:1; /* Metadata Settings */ 464 uint32_t fm_pi:3; /* Protection Information */ 465 uint32_t fm_pil:1; /* Prot. Information Location */ 466 uint32_t fm_ses:3; /* Secure Erase Settings */ 467 uint32_t fm_resvd:20; 468 } b; 469 uint32_t r; 470 } nvme_format_nvm_t; 471 472 473 /* 474 * NVMe Get / Set Features 475 */ 476 #define NVME_FEAT_ARBITRATION 0x1 /* Command Arbitration */ 477 #define NVME_FEAT_POWER_MGMT 0x2 /* Power Management */ 478 #define NVME_FEAT_LBA_RANGE 0x3 /* LBA Range Type */ 479 #define NVME_FEAT_TEMPERATURE 0x4 /* Temperature Threshold */ 480 #define NVME_FEAT_ERROR 0x5 /* Error Recovery */ 481 #define NVME_FEAT_WRITE_CACHE 0x6 /* Volatile Write Cache */ 482 #define NVME_FEAT_NQUEUES 0x7 /* Number of Queues */ 483 #define NVME_FEAT_INTR_COAL 0x8 /* Interrupt Coalescing */ 484 #define NVME_FEAT_INTR_VECT 0x9 /* Interrupt Vector Configuration */ 485 #define NVME_FEAT_WRITE_ATOM 0xa /* Write Atomicity */ 486 #define NVME_FEAT_ASYNC_EVENT 0xb /* Asynchronous Event Configuration */ 487 #define NVME_FEAT_AUTO_PST 0xc /* Autonomous Power State Transition */ 488 /* (1.1) */ 489 490 #define NVME_FEAT_PROGRESS 0x80 /* Software Progress Marker */ 491 492 /* Arbitration Feature */ 493 typedef union { 494 struct { 495 uint8_t arb_ab:3; /* Arbitration Burst */ 496 uint8_t arb_rsvd:5; 497 uint8_t arb_lpw; /* Low Priority Weight */ 498 uint8_t arb_mpw; /* Medium Priority Weight */ 499 uint8_t arb_hpw; /* High Priority Weight */ 500 } b; 501 uint32_t r; 502 } nvme_arbitration_t; 503 504 /* Power Management Feature */ 505 typedef union { 506 struct { 507 uint32_t pm_ps:5; /* Power State */ 508 uint32_t pm_rsvd:27; 509 } b; 510 uint32_t r; 511 } nvme_power_mgmt_t; 512 513 /* LBA Range Type Feature */ 514 typedef union { 515 struct { 516 uint32_t lr_num:6; /* Number of LBA ranges */ 517 uint32_t lr_rsvd:26; 518 } b; 519 uint32_t r; 520 } nvme_lba_range_type_t; 521 522 typedef struct { 523 uint8_t lr_type; /* Type */ 524 struct { /* Attributes */ 525 uint8_t lr_write:1; /* may be overwritten */ 526 uint8_t lr_hidden:1; /* hidden from OS/EFI/BIOS */ 527 uint8_t lr_rsvd1:6; 528 } lr_attr; 529 uint8_t lr_rsvd2[14]; 530 uint64_t lr_slba; /* Starting LBA */ 531 uint64_t lr_nlb; /* Number of Logical Blocks */ 532 uint8_t lr_guid[16]; /* Unique Identifier */ 533 uint8_t lr_rsvd3[16]; 534 } nvme_lba_range_t; 535 536 #define NVME_LBA_RANGE_BUFSIZE 4096 537 538 /* Temperature Threshold Feature */ 539 typedef union { 540 struct { 541 uint16_t tt_tmpth; /* Temperature Threshold */ 542 uint16_t tt_rsvd; 543 } b; 544 uint32_t r; 545 } nvme_temp_threshold_t; 546 547 /* Error Recovery Feature */ 548 typedef union { 549 struct { 550 uint16_t er_tler; /* Time-Limited Error Recovery */ 551 uint16_t er_rsvd; 552 } b; 553 uint32_t r; 554 } nvme_error_recovery_t; 555 556 /* Volatile Write Cache Feature */ 557 typedef union { 558 struct { 559 uint32_t wc_wce:1; /* Volatile Write Cache Enable */ 560 uint32_t wc_rsvd:31; 561 } b; 562 uint32_t r; 563 } nvme_write_cache_t; 564 565 /* Number of Queues Feature */ 566 typedef union { 567 struct { 568 uint16_t nq_nsq; /* Number of Submission Queues */ 569 uint16_t nq_ncq; /* Number of Completion Queues */ 570 } b; 571 uint32_t r; 572 } nvme_nqueues_t; 573 574 /* Interrupt Coalescing Feature */ 575 typedef union { 576 struct { 577 uint8_t ic_thr; /* Aggregation Threshold */ 578 uint8_t ic_time; /* Aggregation Time */ 579 uint16_t ic_rsvd; 580 } b; 581 uint32_t r; 582 } nvme_intr_coal_t; 583 584 /* Interrupt Configuration Features */ 585 typedef union { 586 struct { 587 uint16_t iv_iv; /* Interrupt Vector */ 588 uint16_t iv_cd:1; /* Coalescing Disable */ 589 uint16_t iv_rsvd:15; 590 } b; 591 uint32_t r; 592 } nvme_intr_vect_t; 593 594 /* Write Atomicity Feature */ 595 typedef union { 596 struct { 597 uint32_t wa_dn:1; /* Disable Normal */ 598 uint32_t wa_rsvd:31; 599 } b; 600 uint32_t r; 601 } nvme_write_atomicity_t; 602 603 /* Asynchronous Event Configuration Feature */ 604 typedef union { 605 struct { 606 uint8_t aec_avail:1; /* available space too low */ 607 uint8_t aec_temp:1; /* temperature too high */ 608 uint8_t aec_reliab:1; /* degraded reliability */ 609 uint8_t aec_readonly:1; /* media is read-only */ 610 uint8_t aec_volatile:1; /* volatile memory backup failed */ 611 uint8_t aec_rsvd1:3; 612 uint8_t aec_rsvd2[3]; 613 } b; 614 uint32_t r; 615 } nvme_async_event_conf_t; 616 617 /* Autonomous Power State Transition Feature (1.1) */ 618 typedef union { 619 struct { 620 uint8_t apst_apste:1; /* APST enabled */ 621 uint8_t apst_rsvd:7; 622 } b; 623 uint8_t r; 624 } nvme_auto_power_state_trans_t; 625 626 typedef struct { 627 uint32_t apst_rsvd1:3; 628 uint32_t apst_itps:5; /* Idle Transition Power State */ 629 uint32_t apst_itpt:24; /* Idle Time Prior to Transition */ 630 uint32_t apst_rsvd2; 631 } nvme_auto_power_state_t; 632 633 #define NVME_AUTO_PST_BUFSIZE 256 634 635 /* Software Progress Marker Feature */ 636 typedef union { 637 struct { 638 uint8_t spm_pbslc; /* Pre-Boot Software Load Count */ 639 uint8_t spm_rsvd[3]; 640 } b; 641 uint32_t r; 642 } nvme_software_progress_marker_t; 643 644 /* 645 * Firmware Commit - Command Dword 10 646 */ 647 #define NVME_FWC_SAVE 0x0 /* Save image only */ 648 #define NVME_FWC_SAVE_ACTIVATE 0x1 /* Save and activate at next reset */ 649 #define NVME_FWC_ACTIVATE 0x2 /* Activate slot at next reset */ 650 #define NVME_FWC_ACTIVATE_IMMED 0x3 /* Activate slot immediately */ 651 652 /* 653 * Firmware slot number is only 3 bits, and zero is not allowed. 654 * Valid range is 1 to 7. 655 */ 656 #define NVME_FW_SLOT_MIN 1 /* lowest allowable slot number ... */ 657 #define NVME_FW_SLOT_MAX 7 /* ... and highest */ 658 659 /* 660 * Some constants to make verification of DWORD variables and arguments easier. 661 * A DWORD is 4 bytes. 662 */ 663 #define NVME_DWORD_SHIFT 2 664 #define NVME_DWORD_SIZE (1 << NVME_DWORD_SHIFT) 665 #define NVME_DWORD_MASK (NVME_DWORD_SIZE - 1) 666 667 /* 668 * Maximum offset a firmware image can be load at is the number of 669 * DWORDS in a 32 bit field. Expressed in bytes its is: 670 */ 671 #define NVME_FW_OFFSETB_MAX ((u_longlong_t)UINT32_MAX << NVME_DWORD_SHIFT) 672 673 typedef union { 674 struct { 675 uint32_t fc_slot:3; /* Firmware slot */ 676 uint32_t fc_action:3; /* Commit action */ 677 uint32_t fc_rsvd:26; 678 } b; 679 uint32_t r; 680 } nvme_firmware_commit_dw10_t; 681 682 #pragma pack() /* pack(1) */ 683 684 /* NVMe completion status code type */ 685 #define NVME_CQE_SCT_GENERIC 0 /* Generic Command Status */ 686 #define NVME_CQE_SCT_SPECIFIC 1 /* Command Specific Status */ 687 #define NVME_CQE_SCT_INTEGRITY 2 /* Media and Data Integrity Errors */ 688 #define NVME_CQE_SCT_VENDOR 7 /* Vendor Specific */ 689 690 /* NVMe completion status code (generic) */ 691 #define NVME_CQE_SC_GEN_SUCCESS 0x0 /* Successful Completion */ 692 #define NVME_CQE_SC_GEN_INV_OPC 0x1 /* Invalid Command Opcode */ 693 #define NVME_CQE_SC_GEN_INV_FLD 0x2 /* Invalid Field in Command */ 694 #define NVME_CQE_SC_GEN_ID_CNFL 0x3 /* Command ID Conflict */ 695 #define NVME_CQE_SC_GEN_DATA_XFR_ERR 0x4 /* Data Transfer Error */ 696 #define NVME_CQE_SC_GEN_ABORT_PWRLOSS 0x5 /* Cmds Aborted / Pwr Loss */ 697 #define NVME_CQE_SC_GEN_INTERNAL_ERR 0x6 /* Internal Error */ 698 #define NVME_CQE_SC_GEN_ABORT_REQUEST 0x7 /* Command Abort Requested */ 699 #define NVME_CQE_SC_GEN_ABORT_SQ_DEL 0x8 /* Cmd Aborted / SQ deletion */ 700 #define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9 /* Cmd Aborted / Failed Fused */ 701 #define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa /* Cmd Aborted / Missing Fusd */ 702 #define NVME_CQE_SC_GEN_INV_NS 0xb /* Inval Namespace or Format */ 703 #define NVME_CQE_SC_GEN_CMD_SEQ_ERR 0xc /* Command Sequence Error */ 704 #define NVME_CQE_SC_GEN_INV_SGL_LAST 0xd /* Inval SGL Last Seg Desc */ 705 #define NVME_CQE_SC_GEN_INV_SGL_NUM 0xe /* Inval Number of SGL Desc */ 706 #define NVME_CQE_SC_GEN_INV_DSGL_LEN 0xf /* Data SGL Length Invalid */ 707 #define NVME_CQE_SC_GEN_INV_MSGL_LEN 0x10 /* Metadata SGL Length Inval */ 708 #define NVME_CQE_SC_GEN_INV_SGL_DESC 0x11 /* SGL Descriptor Type Inval */ 709 #define NVME_CQE_SC_GEN_INV_USE_CMB 0x12 /* Inval use of Ctrl Mem Buf */ 710 #define NVME_CQE_SC_GEN_INV_PRP_OFF 0x13 /* PRP Offset Invalid */ 711 #define NVME_CQE_SC_GEN_AWU_EXCEEDED 0x14 /* Atomic Write Unit Exceeded */ 712 713 /* NVMe completion status code (generic NVM commands) */ 714 #define NVME_CQE_SC_GEN_NVM_LBA_RANGE 0x80 /* LBA Out Of Range */ 715 #define NVME_CQE_SC_GEN_NVM_CAP_EXC 0x81 /* Capacity Exceeded */ 716 #define NVME_CQE_SC_GEN_NVM_NS_NOTRDY 0x82 /* Namespace Not Ready */ 717 #define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT 0x83 /* Reservation Conflict */ 718 719 /* NVMe completion status code (command specific) */ 720 #define NVME_CQE_SC_SPC_INV_CQ 0x0 /* Completion Queue Invalid */ 721 #define NVME_CQE_SC_SPC_INV_QID 0x1 /* Invalid Queue Identifier */ 722 #define NVME_CQE_SC_SPC_MAX_QSZ_EXC 0x2 /* Max Queue Size Exceeded */ 723 #define NVME_CQE_SC_SPC_ABRT_CMD_EXC 0x3 /* Abort Cmd Limit Exceeded */ 724 #define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5 /* Async Event Request Limit */ 725 #define NVME_CQE_SC_SPC_INV_FW_SLOT 0x6 /* Invalid Firmware Slot */ 726 #define NVME_CQE_SC_SPC_INV_FW_IMG 0x7 /* Invalid Firmware Image */ 727 #define NVME_CQE_SC_SPC_INV_INT_VECT 0x8 /* Invalid Interrupt Vector */ 728 #define NVME_CQE_SC_SPC_INV_LOG_PAGE 0x9 /* Invalid Log Page */ 729 #define NVME_CQE_SC_SPC_INV_FORMAT 0xa /* Invalid Format */ 730 #define NVME_CQE_SC_SPC_FW_RESET 0xb /* FW Application Reset Reqd */ 731 #define NVME_CQE_SC_SPC_INV_Q_DEL 0xc /* Invalid Queue Deletion */ 732 #define NVME_CQE_SC_SPC_FEAT_SAVE 0xd /* Feature Id Not Saveable */ 733 #define NVME_CQE_SC_SPC_FEAT_CHG 0xe /* Feature Not Changeable */ 734 #define NVME_CQE_SC_SPC_FEAT_NS_SPEC 0xf /* Feature Not Namespace Spec */ 735 #define NVME_CQE_SC_SPC_FW_NSSR 0x10 /* FW Application NSSR Reqd */ 736 #define NVME_CQE_SC_SPC_FW_NEXT_RESET 0x11 /* FW Application Next Reqd */ 737 #define NVME_CQE_SC_SPC_FW_MTFA 0x12 /* FW Application Exceed MTFA */ 738 #define NVME_CQE_SC_SPC_FW_PROHIBITED 0x13 /* FW Application Prohibited */ 739 #define NVME_CQE_SC_SPC_FW_OVERLAP 0x14 /* Overlapping FW ranges */ 740 741 /* NVMe completion status code (NVM command specific */ 742 #define NVME_CQE_SC_SPC_NVM_CNFL_ATTR 0x80 /* Conflicting Attributes */ 743 #define NVME_CQE_SC_SPC_NVM_INV_PROT 0x81 /* Invalid Protection */ 744 #define NVME_CQE_SC_SPC_NVM_READONLY 0x82 /* Write to Read Only Range */ 745 746 /* NVMe completion status code (data / metadata integrity) */ 747 #define NVME_CQE_SC_INT_NVM_WRITE 0x80 /* Write Fault */ 748 #define NVME_CQE_SC_INT_NVM_READ 0x81 /* Unrecovered Read Error */ 749 #define NVME_CQE_SC_INT_NVM_GUARD 0x82 /* Guard Check Error */ 750 #define NVME_CQE_SC_INT_NVM_APPL_TAG 0x83 /* Application Tag Check Err */ 751 #define NVME_CQE_SC_INT_NVM_REF_TAG 0x84 /* Reference Tag Check Err */ 752 #define NVME_CQE_SC_INT_NVM_COMPARE 0x85 /* Compare Failure */ 753 #define NVME_CQE_SC_INT_NVM_ACCESS 0x86 /* Access Denied */ 754 755 #ifdef __cplusplus 756 } 757 #endif 758 759 #endif /* _SYS_NVME_H */ 760