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
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.
13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
17 * NVMe hardware interface
33 #define NVME_MAX_ADMIN_QUEUE_LEN 4096
36 * NVMe registers and register fields
38 #define NVME_REG_CAP 0x0 /* Controller Capabilities */
39 #define NVME_REG_VS 0x8 /* Version */
40 #define NVME_REG_INTMS 0xc /* Interrupt Mask Set */
41 #define NVME_REG_INTMC 0x10 /* Interrupt Mask Clear */
42 #define NVME_REG_CC 0x14 /* Controller Configuration */
43 #define NVME_REG_CSTS 0x1c /* Controller Status */
44 #define NVME_REG_NSSR 0x20 /* NVM Subsystem Reset */
45 #define NVME_REG_AQA 0x24 /* Admin Queue Attributes */
46 #define NVME_REG_ASQ 0x28 /* Admin Submission Queue */
47 #define NVME_REG_ACQ 0x30 /* Admin Completion Qeueu */
48 #define NVME_REG_SQTDBL(nvme, n) \
49 (0x1000 + ((2 * (n)) * nvme->n_doorbell_stride))
50 #define NVME_REG_CQHDBL(nvme, n) \
51 (0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride))
53 #define NVME_CAP_CSS_NVM 1 /* NVM Command Set */
54 #define NVME_CAP_AMS_WRR 1 /* Weighted Round-Robin */
56 /* CAP -- Controller Capabilities */
59 uint16_t cap_mqes
; /* Maximum Queue Entries Supported */
60 uint8_t cap_cqr
:1; /* Contiguous Queues Required */
61 uint8_t cap_ams
:2; /* Arbitration Mechanisms Supported */
63 uint8_t cap_to
; /* Timeout */
64 uint16_t cap_dstrd
:4; /* Doorbell Stride */
65 uint16_t cap_nssrs
:1; /* NVM Subsystem Reset Supported */
66 uint16_t cap_css
:8; /* Command Sets Supported */
68 uint8_t cap_mpsmin
:4; /* Memory Page Size Minimum */
69 uint8_t cap_mpsmax
:4; /* Memory Page Size Maximum */
79 uint8_t vs_mnr
; /* Minor Version Number */
80 uint16_t vs_mjr
; /* Major Version Number */
85 /* CC -- Controller Configuration */
86 #define NVME_CC_SHN_NORMAL 1 /* Normal Shutdown Notification */
87 #define NVME_CC_SHN_ABRUPT 2 /* Abrupt Shutdown Notification */
91 uint16_t cc_en
:1; /* Enable */
93 uint16_t cc_css
:3; /* I/O Command Set Selected */
94 uint16_t cc_mps
:4; /* Memory Page Size */
95 uint16_t cc_ams
:3; /* Arbitration Mechanism Selected */
96 uint16_t cc_shn
:2; /* Shutdown Notification */
97 uint8_t cc_iosqes
:4; /* I/O Submission Queue Entry Size */
98 uint8_t cc_iocqes
:4; /* I/O Completion Queue Entry Size */
104 /* CSTS -- Controller Status */
105 #define NVME_CSTS_SHN_OCCURING 1 /* Shutdown Processing Occuring */
106 #define NVME_CSTS_SHN_COMPLETE 2 /* Shutdown Processing Complete */
110 uint32_t csts_rdy
:1; /* Ready */
111 uint32_t csts_cfs
:1; /* Controller Fatal Status */
112 uint32_t csts_shst
:2; /* Shutdown Status */
113 uint32_t csts_nssro
:1; /* NVM Subsystem Reset Occured */
114 uint32_t csts_rsvd
:28;
119 /* NSSR -- NVM Subsystem Reset */
120 #define NVME_NSSR_NSSRC 0x4e564d65 /* NSSR magic value */
121 typedef uint32_t nvme_reg_nssr_t
;
123 /* AQA -- Admin Queue Attributes */
126 uint16_t aqa_asqs
:12; /* Admin Submission Queue Size */
127 uint16_t aqa_rsvd1
:4;
128 uint16_t aqa_acqs
:12; /* Admin Completion Queue Size */
129 uint16_t aqa_rsvd2
:4;
135 * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is
136 * probably a specification bug. The full 64bit regs are used as base address,
137 * and the lower bits must be zero to ensure alignment on the page size
138 * specified in CC.MPS.
140 /* ASQ -- Admin Submission Queue Base Address */
141 typedef uint64_t nvme_reg_asq_t
; /* Admin Submission Queue Base */
143 /* ACQ -- Admin Completion Queue Base Address */
144 typedef uint64_t nvme_reg_acq_t
; /* Admin Completion Queue Base */
146 /* SQyTDBL -- Submission Queue y Tail Doorbell */
149 uint16_t sqtdbl_sqt
; /* Submission Queue Tail */
150 uint16_t sqtdbl_rsvd
;
155 /* CQyHDBL -- Completion Queue y Head Doorbell */
158 uint16_t cqhdbl_cqh
; /* Completion Queue Head */
159 uint16_t cqhdbl_rsvd
;
165 * NVMe submission queue entries
168 /* NVMe scatter/gather list descriptor */
170 uint64_t sgl_addr
; /* Address */
171 uint32_t sgl_len
; /* Length */
174 uint8_t sgl_type
:4; /* SGL descriptor type */
177 /* NVMe SGL descriptor type */
178 #define NVME_SGL_DATA_BLOCK 0
179 #define NVME_SGL_BIT_BUCKET 1
180 #define NVME_SGL_SEGMENT 2
181 #define NVME_SGL_LAST_SEGMENT 3
182 #define NVME_SGL_VENDOR 0xf
184 /* NVMe submission queue entry */
186 uint8_t sqe_opc
; /* Opcode */
187 uint8_t sqe_fuse
:2; /* Fused Operation */
189 uint8_t sqe_psdt
:1; /* PRP or SGL for Data Transfer */
190 uint16_t sqe_cid
; /* Command Identifier */
191 uint32_t sqe_nsid
; /* Namespace Identifier */
194 uint64_t m_ptr
; /* Metadata Pointer */
195 uint64_t m_sglp
; /* Metadata SGL Segment Pointer */
198 uint64_t d_prp
[2]; /* Physical Page Region Entries 1 & 2 */
199 nvme_sgl_t d_sgl
; /* SGL Entry 1 */
200 } sqe_dptr
; /* Data Pointer */
201 uint32_t sqe_cdw10
; /* Number of Dwords in Data Transfer */
202 uint32_t sqe_cdw11
; /* Number of Dwords in Metadata Xfer */
209 /* NVMe admin command opcodes */
210 #define NVME_OPC_DELETE_SQUEUE 0x0
211 #define NVME_OPC_CREATE_SQUEUE 0x1
212 #define NVME_OPC_GET_LOG_PAGE 0x2
213 #define NVME_OPC_DELETE_CQUEUE 0x4
214 #define NVME_OPC_CREATE_CQUEUE 0x5
215 #define NVME_OPC_IDENTIFY 0x6
216 #define NVME_OPC_ABORT 0x8
217 #define NVME_OPC_SET_FEATURES 0x9
218 #define NVME_OPC_GET_FEATURES 0xa
219 #define NVME_OPC_ASYNC_EVENT 0xc
220 #define NVME_OPC_FW_ACTIVATE 0x10
221 #define NVME_OPC_FW_IMAGE_LOAD 0x11
223 /* NVMe NVM command set specific admin command opcodes */
224 #define NVME_OPC_NVM_FORMAT 0x80
225 #define NVME_OPC_NVM_SEC_SEND 0x81
226 #define NVME_OPC_NVM_SEC_RECV 0x82
228 /* NVMe NVM command opcodes */
229 #define NVME_OPC_NVM_FLUSH 0x0
230 #define NVME_OPC_NVM_WRITE 0x1
231 #define NVME_OPC_NVM_READ 0x2
232 #define NVME_OPC_NVM_WRITE_UNC 0x4
233 #define NVME_OPC_NVM_COMPARE 0x5
234 #define NVME_OPC_NVM_WRITE_ZERO 0x8
235 #define NVME_OPC_NVM_DSET_MGMT 0x9
236 #define NVME_OPC_NVM_RESV_REG 0xd
237 #define NVME_OPC_NVM_RESV_REPRT 0xe
238 #define NVME_OPC_NVM_RESV_ACQ 0x11
239 #define NVME_OPC_NVM_RESV_REL 0x12
242 * NVMe completion queue entry
245 uint16_t sf_p
:1; /* Phase Tag */
246 uint16_t sf_sc
:8; /* Status Code */
247 uint16_t sf_sct
:3; /* Status Code Type */
249 uint16_t sf_m
:1; /* More */
250 uint16_t sf_dnr
:1; /* Do Not Retry */
254 uint32_t cqe_dw0
; /* Command Specific */
256 uint16_t cqe_sqhd
; /* SQ Head Pointer */
257 uint16_t cqe_sqid
; /* SQ Identifier */
258 uint16_t cqe_cid
; /* Command Identifier */
259 nvme_cqe_sf_t cqe_sf
; /* Status Field */
262 /* NVMe completion status code type */
263 #define NVME_CQE_SCT_GENERIC 0 /* Generic Command Status */
264 #define NVME_CQE_SCT_SPECIFIC 1 /* Command Specific Status */
265 #define NVME_CQE_SCT_INTEGRITY 2 /* Media and Data Integrity Errors */
266 #define NVME_CQE_SCT_VENDOR 7 /* Vendor Specific */
268 /* NVMe completion status code (generic) */
269 #define NVME_CQE_SC_GEN_SUCCESS 0x0 /* Successful Completion */
270 #define NVME_CQE_SC_GEN_INV_OPC 0x1 /* Invalid Command Opcode */
271 #define NVME_CQE_SC_GEN_INV_FLD 0x2 /* Invalid Field in Command */
272 #define NVME_CQE_SC_GEN_ID_CNFL 0x3 /* Command ID Conflict */
273 #define NVME_CQE_SC_GEN_DATA_XFR_ERR 0x4 /* Data Transfer Error */
274 #define NVME_CQE_SC_GEN_ABORT_PWRLOSS 0x5 /* Cmds Aborted / Pwr Loss */
275 #define NVME_CQE_SC_GEN_INTERNAL_ERR 0x6 /* Internal Error */
276 #define NVME_CQE_SC_GEN_ABORT_REQUEST 0x7 /* Command Abort Requested */
277 #define NVME_CQE_SC_GEN_ABORT_SQ_DEL 0x8 /* Cmd Aborted / SQ deletion */
278 #define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9 /* Cmd Aborted / Failed Fused */
279 #define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa /* Cmd Aborted / Missing Fusd */
280 #define NVME_CQE_SC_GEN_INV_NS 0xb /* Inval Namespace or Format */
281 #define NVME_CQE_SC_GEN_CMD_SEQ_ERR 0xc /* Command Sequence Error */
282 #define NVME_CQE_SC_GEN_INV_SGL_LAST 0xd /* Inval SGL Last Seg Desc */
283 #define NVME_CQE_SC_GEN_INV_SGL_NUM 0xe /* Inval Number of SGL Desc */
284 #define NVME_CQE_SC_GEN_INV_DSGL_LEN 0xf /* Data SGL Length Invalid */
285 #define NVME_CQE_SC_GEN_INV_MSGL_LEN 0x10 /* Metadata SGL Length Inval */
286 #define NVME_CQE_SC_GEN_INV_SGL_DESC 0x11 /* SGL Descriptor Type Inval */
288 /* NVMe completion status code (generic NVM commands) */
289 #define NVME_CQE_SC_GEN_NVM_LBA_RANGE 0x80 /* LBA Out Of Range */
290 #define NVME_CQE_SC_GEN_NVM_CAP_EXC 0x81 /* Capacity Exceeded */
291 #define NVME_CQE_SC_GEN_NVM_NS_NOTRDY 0x82 /* Namespace Not Ready */
292 #define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT 0x83 /* Reservation Conflict */
294 /* NVMe completion status code (command specific) */
295 #define NVME_CQE_SC_SPC_INV_CQ 0x0 /* Completion Queue Invalid */
296 #define NVME_CQE_SC_SPC_INV_QID 0x1 /* Invalid Queue Identifier */
297 #define NVME_CQE_SC_SPC_MAX_QSZ_EXC 0x2 /* Max Queue Size Exceeded */
298 #define NVME_CQE_SC_SPC_ABRT_CMD_EXC 0x3 /* Abort Cmd Limit Exceeded */
299 #define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5 /* Async Event Request Limit */
300 #define NVME_CQE_SC_SPC_INV_FW_SLOT 0x6 /* Invalid Firmware Slot */
301 #define NVME_CQE_SC_SPC_INV_FW_IMG 0x7 /* Invalid Firmware Image */
302 #define NVME_CQE_SC_SPC_INV_INT_VECT 0x8 /* Invalid Interrupt Vector */
303 #define NVME_CQE_SC_SPC_INV_LOG_PAGE 0x9 /* Invalid Log Page */
304 #define NVME_CQE_SC_SPC_INV_FORMAT 0xa /* Invalid Format */
305 #define NVME_CQE_SC_SPC_FW_RESET 0xb /* FW Application Reset Reqd */
306 #define NVME_CQE_SC_SPC_INV_Q_DEL 0xc /* Invalid Queue Deletion */
307 #define NVME_CQE_SC_SPC_FEAT_SAVE 0xd /* Feature Id Not Saveable */
308 #define NVME_CQE_SC_SPC_FEAT_CHG 0xe /* Feature Not Changeable */
309 #define NVME_CQE_SC_SPC_FEAT_NS_SPEC 0xf /* Feature Not Namespace Spec */
310 #define NVME_CQE_SC_SPC_FW_NSSR 0x10 /* FW Application NSSR Reqd */
312 /* NVMe completion status code (NVM command specific */
313 #define NVME_CQE_SC_SPC_NVM_CNFL_ATTR 0x80 /* Conflicting Attributes */
314 #define NVME_CQE_SC_SPC_NVM_INV_PROT 0x81 /* Invalid Protection */
315 #define NVME_CQE_SC_SPC_NVM_READONLY 0x82 /* Write to Read Only Range */
317 /* NVMe completion status code (data / metadata integrity) */
318 #define NVME_CQE_SC_INT_NVM_WRITE 0x80 /* Write Fault */
319 #define NVME_CQE_SC_INT_NVM_READ 0x81 /* Unrecovered Read Error */
320 #define NVME_CQE_SC_INT_NVM_GUARD 0x82 /* Guard Check Error */
321 #define NVME_CQE_SC_INT_NVM_APPL_TAG 0x83 /* Application Tag Check Err */
322 #define NVME_CQE_SC_INT_NVM_REF_TAG 0x84 /* Reference Tag Check Err */
323 #define NVME_CQE_SC_INT_NVM_COMPARE 0x85 /* Compare Failure */
324 #define NVME_CQE_SC_INT_NVM_ACCESS 0x86 /* Access Denied */
327 * NVMe Asynchronous Event Request
329 #define NVME_ASYNC_TYPE_ERROR 0x0 /* Error Status */
330 #define NVME_ASYNC_TYPE_HEALTH 0x1 /* SMART/Health Status */
331 #define NVME_ASYNC_TYPE_VENDOR 0x7 /* vendor specific */
333 #define NVME_ASYNC_ERROR_INV_SQ 0x0 /* Invalid Submission Queue */
334 #define NVME_ASYNC_ERROR_INV_DBL 0x1 /* Invalid Doorbell Write */
335 #define NVME_ASYNC_ERROR_DIAGFAIL 0x2 /* Diagnostic Failure */
336 #define NVME_ASYNC_ERROR_PERSISTENT 0x3 /* Persistent Internal Error */
337 #define NVME_ASYNC_ERROR_TRANSIENT 0x4 /* Transient Internal Error */
338 #define NVME_ASYNC_ERROR_FW_LOAD 0x5 /* Firmware Image Load Error */
340 #define NVME_ASYNC_HEALTH_RELIABILITY 0x0 /* Device Reliability */
341 #define NVME_ASYNC_HEALTH_TEMPERATURE 0x1 /* Temp. Above Threshold */
342 #define NVME_ASYNC_HEALTH_SPARE 0x2 /* Spare Below Threshold */
346 uint8_t ae_type
:3; /* Asynchronous Event Type */
348 uint8_t ae_info
; /* Asynchronous Event Info */
349 uint8_t ae_logpage
; /* Associated Log Page */
353 } nvme_async_event_t
;
356 * NVMe Create Completion/Submission Queue
360 uint16_t q_qid
; /* Queue Identifier */
361 uint16_t q_qsize
; /* Queue Size */
364 } nvme_create_queue_dw10_t
;
368 uint16_t cq_pc
:1; /* Physically Contiguous */
369 uint16_t cq_ien
:1; /* Interrupts Enabled */
371 uint16_t cq_iv
; /* Interrupt Vector */
374 } nvme_create_cq_dw11_t
;
378 uint16_t sq_pc
:1; /* Physically Contiguous */
379 uint16_t sq_qprio
:2; /* Queue Priority */
381 uint16_t sq_cqid
; /* Completion Queue ID */
384 } nvme_create_sq_dw11_t
;
390 /* NVMe Identify parameters (cdw10) */
391 #define NVME_IDENTIFY_NSID 0x0 /* Identify Namespace */
392 #define NVME_IDENTIFY_CTRL 0x1 /* Identify Controller */
393 #define NVME_IDENTIFY_LIST 0x2 /* Identify List Namespaces */
395 #define NVME_IDENTIFY_BUFSIZE 4096 /* buffer size for Identify */
397 /* NVMe Queue Entry Size bitfield */
399 uint8_t qes_min
:4; /* minimum entry size */
400 uint8_t qes_max
:4; /* maximum entry size */
403 /* NVMe Power State Descriptor */
405 uint16_t psd_mp
; /* Maximum Power */
407 uint32_t psd_enlat
; /* Entry Latency */
408 uint32_t psd_exlat
; /* Exit Latency */
409 uint8_t psd_rrt
:5; /* Relative Read Throughput */
411 uint8_t psd_rrl
:5; /* Relative Read Latency */
413 uint8_t psd_rwt
:5; /* Relative Write Throughput */
415 uint8_t psd_rwl
:5; /* Relative Write Latency */
417 uint8_t psd_rsvd6
[16];
420 /* NVMe Identify Controller Data Structure */
422 /* Controller Capabilities & Features */
423 uint16_t id_vid
; /* PCI vendor ID */
424 uint16_t id_ssvid
; /* PCI subsystem vendor ID */
425 char id_serial
[20]; /* Serial Number */
426 char id_model
[40]; /* Model Number */
427 char id_fwrev
[8]; /* Firmware Revision */
428 uint8_t id_rab
; /* Recommended Arbitration Burst */
429 uint8_t id_oui
[3]; /* vendor IEEE OUI */
430 struct { /* Multi-Interface Capabilities */
431 uint8_t m_multi
:1; /* HW has multiple PCIe interfaces */
434 uint8_t id_mdts
; /* Maximum Data Transfer Size */
435 uint8_t id_rsvd_cc
[256 - 78];
437 /* Admin Command Set Attributes */
438 struct { /* Optional Admin Command Support */
439 uint16_t oa_security
:1; /* Security Send & Receive */
440 uint16_t oa_format
:1; /* Format NVM */
441 uint16_t oa_firmare
:1; /* Firmware Activate & Download */
444 uint8_t id_acl
; /* Abort Command Limit */
445 uint8_t id_aerl
; /* Asynchronous Event Request Limit */
446 struct { /* Firmware Updates */
447 uint8_t fw_readonly
:1; /* Slot 1 is Read-Only */
448 uint8_t fw_nslot
:3; /* number of firmware slots */
451 struct { /* Log Page Attributes */
452 uint8_t lp_smart
:1; /* SMART/Health information per NS */
455 uint8_t id_elpe
; /* Error Log Page Entries */
456 uint8_t id_npss
; /* Number of Power States */
457 struct { /* Admin Vendor Specific Command Conf */
458 uint8_t av_spec
:1; /* use format from spec */
461 uint8_t id_rsvd_ac
[256 - 9];
463 /* NVM Command Set Attributes */
464 nvme_idctl_qes_t id_sqes
; /* Submission Queue Entry Size */
465 nvme_idctl_qes_t id_cqes
; /* Completion Queue Entry Size */
466 uint16_t id_rsvd_nc_1
;
467 uint32_t id_nn
; /* Number of Namespaces */
468 struct { /* Optional NVM Command Support */
469 uint16_t on_compare
:1; /* Compare */
470 uint16_t on_wr_unc
:1; /* Write Uncorrectable */
471 uint16_t on_dset_mgmt
:1; /* Dataset Management */
474 struct { /* Fused Operation Support */
475 uint16_t f_cmp_wr
:1; /* Compare and Write */
478 struct { /* Format NVM Attributes */
479 uint8_t fn_format
:1; /* Format applies to all NS */
480 uint8_t fn_sec_erase
:1; /* Secure Erase applies to all NS */
481 uint8_t fn_crypt_erase
:1; /* Cryptographic Erase supported */
484 struct { /* Volatile Write Cache */
485 uint8_t vwc_present
:1; /* Volatile Write Cache present */
488 uint16_t id_awun
; /* Atomic Write Unit Normal */
489 uint16_t id_awupf
; /* Atomic Write Unit Power Fail */
490 struct { /* NVM Vendor Specific Command Conf */
491 uint8_t nv_spec
:1; /* use format from spec */
494 uint8_t id_rsvd_nc_2
[192 - 19];
496 /* I/O Command Set Attributes */
497 uint8_t id_rsvd_ioc
[1344];
499 /* Power State Descriptors */
500 nvme_idctl_psd_t id_psd
[32];
502 /* Vendor Specific */
504 } nvme_identify_ctrl_t
;
506 /* NVMe Identify Namespace LBA Format */
508 uint16_t lbaf_ms
; /* Metadata Size */
509 uint8_t lbaf_lbads
; /* LBA Data Size */
510 uint8_t lbaf_rp
:2; /* Relative Performance */
511 uint8_t lbaf_rsvd1
:6;
514 /* NVMe Identify Namespace Data Structure */
516 uint64_t id_nsize
; /* Namespace Size */
517 uint64_t id_ncap
; /* Namespace Capacity */
518 uint64_t id_nuse
; /* Namespace Utilization */
519 struct { /* Namespace Features */
520 uint8_t f_thin
:1; /* Thin Provisioning */
523 uint8_t id_nlbaf
; /* Number of LBA formats */
524 struct { /* Formatted LBA size */
525 uint8_t lba_format
:4; /* LBA format */
526 uint8_t lba_extlba
:1; /* extended LBA (includes metadata) */
529 struct { /* Metadata Capabilities */
530 uint8_t mc_extlba
:1; /* extended LBA transfers */
531 uint8_t mc_separate
:1; /* separate metadata transfers */
534 struct { /* Data Protection Capabilities */
535 uint8_t dp_type1
:1; /* Protection Information Type 1 */
536 uint8_t dp_type2
:1; /* Protection Information Type 2 */
537 uint8_t dp_type3
:1; /* Protection Information Type 3 */
538 uint8_t dp_first
:1; /* first 8 bytes of metadata */
539 uint8_t dp_last
:1; /* last 8 bytes of metadata */
541 struct { /* Data Protection Settings */
542 uint8_t dp_pinfo
:3; /* Protection Information enabled */
543 uint8_t dp_first
:1; /* first 8 bytes of metadata */
545 uint8_t id_rsvd1
[128 - 30];
546 nvme_idns_lbaf_t id_lbaf
[16]; /* LBA Formats */
548 uint8_t id_rsvd2
[192];
550 uint8_t id_vs
[3712]; /* Vendor Specific */
551 } nvme_identify_nsid_t
;
559 uint16_t ac_sqid
; /* Submission Queue ID */
560 uint16_t ac_cid
; /* Command ID */
567 * NVMe Get / Set Features
569 #define NVME_FEAT_ARBITRATION 0x1 /* Command Arbitration */
570 #define NVME_FEAT_POWER_MGMT 0x2 /* Power Management */
571 #define NVME_FEAT_LBA_RANGE 0x3 /* LBA Range Type */
572 #define NVME_FEAT_TEMPERATURE 0x4 /* Temperature Threshold */
573 #define NVME_FEAT_ERROR 0x5 /* Error Recovery */
574 #define NVME_FEAT_WRITE_CACHE 0x6 /* Volatile Write Cache */
575 #define NVME_FEAT_NQUEUES 0x7 /* Number of Queues */
576 #define NVME_FEAT_INTR_COAL 0x8 /* Interrupt Coalescing */
577 #define NVME_FEAT_INTR_VECT 0x9 /* Interrupt Vector Configuration */
578 #define NVME_FEAT_WRITE_ATOM 0xa /* Write Atomicity */
579 #define NVME_FEAT_ASYNC_EVENT 0xb /* Asynchronous Event Configuration */
581 #define NVME_FEAT_PROGRESS 0x80 /* Software Progress Marker */
583 /* Arbitration Feature */
585 uint8_t arb_ab
:3; /* Arbitration Burst */
587 uint8_t arb_lpw
; /* Low Priority Weight */
588 uint8_t arb_mpw
; /* Medium Priority Weight */
589 uint8_t arb_hpw
; /* High Priority Weight */
590 } nvme_arbitration_dw11_t
;
592 /* LBA Range Type Feature */
594 uint32_t lr_num
:6; /* Number of LBA ranges */
596 } nvme_lba_range_type_dw11_t
;
599 uint8_t lr_type
; /* Type */
600 struct { /* Attributes */
601 uint8_t lr_write
:1; /* may be overwritten */
602 uint8_t lr_hidden
:1; /* hidden from OS/EFI/BIOS */
605 uint8_t lr_rsvd2
[14];
606 uint64_t lr_slba
; /* Starting LBA */
607 uint64_t lr_nlb
; /* Number of Logical Blocks */
608 uint8_t lr_guid
[16]; /* Unique Identifier */
609 uint8_t lr_rsvd3
[16];
610 } nvme_lba_range_type_t
;
612 /* Number of Queues */
615 uint16_t nq_nsq
; /* Number of Submission Queues */
616 uint16_t nq_ncq
; /* Number of Completion Queues */
625 #define NVME_LOGPAGE_ERROR 0x1 /* Error Information */
626 #define NVME_LOGPAGE_HEALTH 0x2 /* SMART/Health Information */
627 #define NVME_LOGPAGE_FWSLOT 0x3 /* Firmware Slot Information */
631 uint8_t lp_lid
; /* Log Page Identifier */
633 uint16_t lp_numd
:12; /* Number of Dwords */
640 uint64_t el_count
; /* Error Count */
641 uint16_t el_sqid
; /* Submission Queue ID */
642 uint16_t el_cid
; /* Command ID */
643 nvme_cqe_sf_t el_sf
; /* Status Field */
644 uint8_t el_byte
; /* Parameter Error Location byte */
645 uint8_t el_bit
:3; /* Parameter Error Location bit */
647 uint64_t el_lba
; /* Logical Block Address */
648 uint32_t el_nsid
; /* Namespace ID */
649 uint8_t el_vendor
; /* Vendor Specific Information avail */
650 uint8_t el_rsvd2
[64 - 29];
651 } nvme_error_log_entry_t
;
659 uint8_t hl_crit_warn
; /* Critical Warning */
660 uint16_t hl_temp
; /* Temperature */
661 uint8_t hl_avail_spare
; /* Available Spare */
662 uint8_t hl_avail_spare_thr
; /* Available Spare Threshold */
663 uint8_t hl_used
; /* Percentage Used */
664 uint8_t hl_rsvd1
[32 - 6];
665 nvme_uint128_t hl_data_read
; /* Data Units Read */
666 nvme_uint128_t hl_data_write
; /* Data Units Written */
667 nvme_uint128_t hl_host_read
; /* Host Read Commands */
668 nvme_uint128_t hl_host_write
; /* Host Write Commands */
669 nvme_uint128_t hl_ctrl_busy
; /* Controller Busy Time */
670 nvme_uint128_t hl_power_cycles
; /* Power Cycles */
671 nvme_uint128_t hl_power_on_hours
; /* Power On Hours */
672 nvme_uint128_t hl_unsafe_shutdn
; /* Unsafe Shutdowns */
673 nvme_uint128_t hl_media_errors
; /* Media Errors */
674 nvme_uint128_t hl_errors_logged
; /* Number of errors logged */
675 uint8_t hl_rsvd2
[512 - 192];
679 uint8_t fw_afi
:3; /* Active Firmware Slot */
682 char fw_frs
[7][8]; /* Firmware Revision / Slot */
683 uint8_t fw_rsvd3
[512 - 64];
690 #pragma pack() /* pack(1) */
692 #endif /* _NVME_REG_H */