bmake-ify mega_sas
[unleashed.git] / usr / src / uts / common / io / nvme / nvme_reg.h
blobacff0e2362fa8a81ae4a04f774ae56db30ae773c
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.
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 2016 Nexenta Systems, Inc. All rights reserved.
17 * NVMe hardware interface
20 #ifndef _NVME_REG_H
21 #define _NVME_REG_H
23 #include <sys/nvme.h>
25 #pragma pack(1)
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
33 * NVMe constants
35 #define NVME_MAX_ADMIN_QUEUE_LEN 4096
38 * NVMe registers and register fields
40 #define NVME_REG_CAP 0x0 /* Controller Capabilities */
41 #define NVME_REG_VS 0x8 /* Version */
42 #define NVME_REG_INTMS 0xc /* Interrupt Mask Set */
43 #define NVME_REG_INTMC 0x10 /* Interrupt Mask Clear */
44 #define NVME_REG_CC 0x14 /* Controller Configuration */
45 #define NVME_REG_CSTS 0x1c /* Controller Status */
46 #define NVME_REG_NSSR 0x20 /* NVM Subsystem Reset */
47 #define NVME_REG_AQA 0x24 /* Admin Queue Attributes */
48 #define NVME_REG_ASQ 0x28 /* Admin Submission Queue */
49 #define NVME_REG_ACQ 0x30 /* Admin Completion Qeueu */
50 #define NVME_REG_SQTDBL(nvme, n) \
51 (0x1000 + ((2 * (n)) * nvme->n_doorbell_stride))
52 #define NVME_REG_CQHDBL(nvme, n) \
53 (0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride))
55 #define NVME_CAP_CSS_NVM 1 /* NVM Command Set */
56 #define NVME_CAP_AMS_WRR 1 /* Weighted Round-Robin */
58 /* CAP -- Controller Capabilities */
59 typedef union {
60 struct {
61 uint16_t cap_mqes; /* Maximum Queue Entries Supported */
62 uint8_t cap_cqr:1; /* Contiguous Queues Required */
63 uint8_t cap_ams:2; /* Arbitration Mechanisms Supported */
64 uint8_t cap_rsvd1:5;
65 uint8_t cap_to; /* Timeout */
66 uint16_t cap_dstrd:4; /* Doorbell Stride */
67 uint16_t cap_nssrs:1; /* NVM Subsystem Reset Supported */
68 uint16_t cap_css:8; /* Command Sets Supported */
69 uint16_t cap_rsvd2:3;
70 uint8_t cap_mpsmin:4; /* Memory Page Size Minimum */
71 uint8_t cap_mpsmax:4; /* Memory Page Size Maximum */
72 uint8_t cap_rsvd3;
73 } b;
74 uint64_t r;
75 } nvme_reg_cap_t;
77 /* VS -- Version */
78 typedef union {
79 struct {
80 uint8_t vs_rsvd;
81 uint8_t vs_mnr; /* Minor Version Number */
82 uint16_t vs_mjr; /* Major Version Number */
83 } b;
84 uint32_t r;
85 } nvme_reg_vs_t;
87 /* CC -- Controller Configuration */
88 #define NVME_CC_SHN_NORMAL 1 /* Normal Shutdown Notification */
89 #define NVME_CC_SHN_ABRUPT 2 /* Abrupt Shutdown Notification */
91 typedef union {
92 struct {
93 uint16_t cc_en:1; /* Enable */
94 uint16_t cc_rsvd1:3;
95 uint16_t cc_css:3; /* I/O Command Set Selected */
96 uint16_t cc_mps:4; /* Memory Page Size */
97 uint16_t cc_ams:3; /* Arbitration Mechanism Selected */
98 uint16_t cc_shn:2; /* Shutdown Notification */
99 uint8_t cc_iosqes:4; /* I/O Submission Queue Entry Size */
100 uint8_t cc_iocqes:4; /* I/O Completion Queue Entry Size */
101 uint8_t cc_rsvd2;
102 } b;
103 uint32_t r;
104 } nvme_reg_cc_t;
106 /* CSTS -- Controller Status */
107 #define NVME_CSTS_SHN_OCCURING 1 /* Shutdown Processing Occuring */
108 #define NVME_CSTS_SHN_COMPLETE 2 /* Shutdown Processing Complete */
110 typedef union {
111 struct {
112 uint32_t csts_rdy:1; /* Ready */
113 uint32_t csts_cfs:1; /* Controller Fatal Status */
114 uint32_t csts_shst:2; /* Shutdown Status */
115 uint32_t csts_nssro:1; /* NVM Subsystem Reset Occured */
116 uint32_t csts_rsvd:27;
117 } b;
118 uint32_t r;
119 } nvme_reg_csts_t;
121 /* NSSR -- NVM Subsystem Reset */
122 #define NVME_NSSR_NSSRC 0x4e564d65 /* NSSR magic value */
123 typedef uint32_t nvme_reg_nssr_t;
125 /* AQA -- Admin Queue Attributes */
126 typedef union {
127 struct {
128 uint16_t aqa_asqs:12; /* Admin Submission Queue Size */
129 uint16_t aqa_rsvd1:4;
130 uint16_t aqa_acqs:12; /* Admin Completion Queue Size */
131 uint16_t aqa_rsvd2:4;
132 } b;
133 uint32_t r;
134 } nvme_reg_aqa_t;
137 * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is
138 * probably a specification bug. The full 64bit regs are used as base address,
139 * and the lower bits must be zero to ensure alignment on the page size
140 * specified in CC.MPS.
142 /* ASQ -- Admin Submission Queue Base Address */
143 typedef uint64_t nvme_reg_asq_t; /* Admin Submission Queue Base */
145 /* ACQ -- Admin Completion Queue Base Address */
146 typedef uint64_t nvme_reg_acq_t; /* Admin Completion Queue Base */
148 /* SQyTDBL -- Submission Queue y Tail Doorbell */
149 typedef union {
150 struct {
151 uint16_t sqtdbl_sqt; /* Submission Queue Tail */
152 uint16_t sqtdbl_rsvd;
153 } b;
154 uint32_t r;
155 } nvme_reg_sqtdbl_t;
157 /* CQyHDBL -- Completion Queue y Head Doorbell */
158 typedef union {
159 struct {
160 uint16_t cqhdbl_cqh; /* Completion Queue Head */
161 uint16_t cqhdbl_rsvd;
162 } b;
163 uint32_t r;
164 } nvme_reg_cqhdbl_t;
167 * NVMe submission queue entries
170 /* NVMe scatter/gather list descriptor */
171 typedef struct {
172 uint64_t sgl_addr; /* Address */
173 uint32_t sgl_len; /* Length */
174 uint8_t sgl_rsvd[3];
175 uint8_t sgl_zero:4;
176 uint8_t sgl_type:4; /* SGL descriptor type */
177 } nvme_sgl_t;
179 /* NVMe SGL descriptor type */
180 #define NVME_SGL_DATA_BLOCK 0
181 #define NVME_SGL_BIT_BUCKET 1
182 #define NVME_SGL_SEGMENT 2
183 #define NVME_SGL_LAST_SEGMENT 3
184 #define NVME_SGL_VENDOR 0xf
186 /* NVMe submission queue entry */
187 typedef struct {
188 uint8_t sqe_opc; /* Opcode */
189 uint8_t sqe_fuse:2; /* Fused Operation */
190 uint8_t sqe_rsvd:5;
191 uint8_t sqe_psdt:1; /* PRP or SGL for Data Transfer */
192 uint16_t sqe_cid; /* Command Identifier */
193 uint32_t sqe_nsid; /* Namespace Identifier */
194 uint64_t sqe_rsvd1;
195 union {
196 uint64_t m_ptr; /* Metadata Pointer */
197 uint64_t m_sglp; /* Metadata SGL Segment Pointer */
198 } sqe_m;
199 union {
200 uint64_t d_prp[2]; /* Physical Page Region Entries 1 & 2 */
201 nvme_sgl_t d_sgl; /* SGL Entry 1 */
202 } sqe_dptr; /* Data Pointer */
203 uint32_t sqe_cdw10; /* Number of Dwords in Data Transfer */
204 uint32_t sqe_cdw11; /* Number of Dwords in Metadata Xfer */
205 uint32_t sqe_cdw12;
206 uint32_t sqe_cdw13;
207 uint32_t sqe_cdw14;
208 uint32_t sqe_cdw15;
209 } nvme_sqe_t;
211 /* NVMe admin command opcodes */
212 #define NVME_OPC_DELETE_SQUEUE 0x0
213 #define NVME_OPC_CREATE_SQUEUE 0x1
214 #define NVME_OPC_GET_LOG_PAGE 0x2
215 #define NVME_OPC_DELETE_CQUEUE 0x4
216 #define NVME_OPC_CREATE_CQUEUE 0x5
217 #define NVME_OPC_IDENTIFY 0x6
218 #define NVME_OPC_ABORT 0x8
219 #define NVME_OPC_SET_FEATURES 0x9
220 #define NVME_OPC_GET_FEATURES 0xa
221 #define NVME_OPC_ASYNC_EVENT 0xc
222 #define NVME_OPC_FW_ACTIVATE 0x10
223 #define NVME_OPC_FW_IMAGE_LOAD 0x11
225 /* NVMe NVM command set specific admin command opcodes */
226 #define NVME_OPC_NVM_FORMAT 0x80
227 #define NVME_OPC_NVM_SEC_SEND 0x81
228 #define NVME_OPC_NVM_SEC_RECV 0x82
230 /* NVMe NVM command opcodes */
231 #define NVME_OPC_NVM_FLUSH 0x0
232 #define NVME_OPC_NVM_WRITE 0x1
233 #define NVME_OPC_NVM_READ 0x2
234 #define NVME_OPC_NVM_WRITE_UNC 0x4
235 #define NVME_OPC_NVM_COMPARE 0x5
236 #define NVME_OPC_NVM_WRITE_ZERO 0x8
237 #define NVME_OPC_NVM_DSET_MGMT 0x9
238 #define NVME_OPC_NVM_RESV_REG 0xd
239 #define NVME_OPC_NVM_RESV_REPRT 0xe
240 #define NVME_OPC_NVM_RESV_ACQ 0x11
241 #define NVME_OPC_NVM_RESV_REL 0x12
244 * NVMe completion queue entry
246 typedef struct {
247 uint32_t cqe_dw0; /* Command Specific */
248 uint32_t cqe_rsvd1;
249 uint16_t cqe_sqhd; /* SQ Head Pointer */
250 uint16_t cqe_sqid; /* SQ Identifier */
251 uint16_t cqe_cid; /* Command Identifier */
252 nvme_cqe_sf_t cqe_sf; /* Status Field */
253 } nvme_cqe_t;
255 /* NVMe completion status code type */
256 #define NVME_CQE_SCT_GENERIC 0 /* Generic Command Status */
257 #define NVME_CQE_SCT_SPECIFIC 1 /* Command Specific Status */
258 #define NVME_CQE_SCT_INTEGRITY 2 /* Media and Data Integrity Errors */
259 #define NVME_CQE_SCT_VENDOR 7 /* Vendor Specific */
261 /* NVMe completion status code (generic) */
262 #define NVME_CQE_SC_GEN_SUCCESS 0x0 /* Successful Completion */
263 #define NVME_CQE_SC_GEN_INV_OPC 0x1 /* Invalid Command Opcode */
264 #define NVME_CQE_SC_GEN_INV_FLD 0x2 /* Invalid Field in Command */
265 #define NVME_CQE_SC_GEN_ID_CNFL 0x3 /* Command ID Conflict */
266 #define NVME_CQE_SC_GEN_DATA_XFR_ERR 0x4 /* Data Transfer Error */
267 #define NVME_CQE_SC_GEN_ABORT_PWRLOSS 0x5 /* Cmds Aborted / Pwr Loss */
268 #define NVME_CQE_SC_GEN_INTERNAL_ERR 0x6 /* Internal Error */
269 #define NVME_CQE_SC_GEN_ABORT_REQUEST 0x7 /* Command Abort Requested */
270 #define NVME_CQE_SC_GEN_ABORT_SQ_DEL 0x8 /* Cmd Aborted / SQ deletion */
271 #define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9 /* Cmd Aborted / Failed Fused */
272 #define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa /* Cmd Aborted / Missing Fusd */
273 #define NVME_CQE_SC_GEN_INV_NS 0xb /* Inval Namespace or Format */
274 #define NVME_CQE_SC_GEN_CMD_SEQ_ERR 0xc /* Command Sequence Error */
275 #define NVME_CQE_SC_GEN_INV_SGL_LAST 0xd /* Inval SGL Last Seg Desc */
276 #define NVME_CQE_SC_GEN_INV_SGL_NUM 0xe /* Inval Number of SGL Desc */
277 #define NVME_CQE_SC_GEN_INV_DSGL_LEN 0xf /* Data SGL Length Invalid */
278 #define NVME_CQE_SC_GEN_INV_MSGL_LEN 0x10 /* Metadata SGL Length Inval */
279 #define NVME_CQE_SC_GEN_INV_SGL_DESC 0x11 /* SGL Descriptor Type Inval */
281 /* NVMe completion status code (generic NVM commands) */
282 #define NVME_CQE_SC_GEN_NVM_LBA_RANGE 0x80 /* LBA Out Of Range */
283 #define NVME_CQE_SC_GEN_NVM_CAP_EXC 0x81 /* Capacity Exceeded */
284 #define NVME_CQE_SC_GEN_NVM_NS_NOTRDY 0x82 /* Namespace Not Ready */
285 #define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT 0x83 /* Reservation Conflict */
287 /* NVMe completion status code (command specific) */
288 #define NVME_CQE_SC_SPC_INV_CQ 0x0 /* Completion Queue Invalid */
289 #define NVME_CQE_SC_SPC_INV_QID 0x1 /* Invalid Queue Identifier */
290 #define NVME_CQE_SC_SPC_MAX_QSZ_EXC 0x2 /* Max Queue Size Exceeded */
291 #define NVME_CQE_SC_SPC_ABRT_CMD_EXC 0x3 /* Abort Cmd Limit Exceeded */
292 #define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5 /* Async Event Request Limit */
293 #define NVME_CQE_SC_SPC_INV_FW_SLOT 0x6 /* Invalid Firmware Slot */
294 #define NVME_CQE_SC_SPC_INV_FW_IMG 0x7 /* Invalid Firmware Image */
295 #define NVME_CQE_SC_SPC_INV_INT_VECT 0x8 /* Invalid Interrupt Vector */
296 #define NVME_CQE_SC_SPC_INV_LOG_PAGE 0x9 /* Invalid Log Page */
297 #define NVME_CQE_SC_SPC_INV_FORMAT 0xa /* Invalid Format */
298 #define NVME_CQE_SC_SPC_FW_RESET 0xb /* FW Application Reset Reqd */
299 #define NVME_CQE_SC_SPC_INV_Q_DEL 0xc /* Invalid Queue Deletion */
300 #define NVME_CQE_SC_SPC_FEAT_SAVE 0xd /* Feature Id Not Saveable */
301 #define NVME_CQE_SC_SPC_FEAT_CHG 0xe /* Feature Not Changeable */
302 #define NVME_CQE_SC_SPC_FEAT_NS_SPEC 0xf /* Feature Not Namespace Spec */
303 #define NVME_CQE_SC_SPC_FW_NSSR 0x10 /* FW Application NSSR Reqd */
305 /* NVMe completion status code (NVM command specific */
306 #define NVME_CQE_SC_SPC_NVM_CNFL_ATTR 0x80 /* Conflicting Attributes */
307 #define NVME_CQE_SC_SPC_NVM_INV_PROT 0x81 /* Invalid Protection */
308 #define NVME_CQE_SC_SPC_NVM_READONLY 0x82 /* Write to Read Only Range */
310 /* NVMe completion status code (data / metadata integrity) */
311 #define NVME_CQE_SC_INT_NVM_WRITE 0x80 /* Write Fault */
312 #define NVME_CQE_SC_INT_NVM_READ 0x81 /* Unrecovered Read Error */
313 #define NVME_CQE_SC_INT_NVM_GUARD 0x82 /* Guard Check Error */
314 #define NVME_CQE_SC_INT_NVM_APPL_TAG 0x83 /* Application Tag Check Err */
315 #define NVME_CQE_SC_INT_NVM_REF_TAG 0x84 /* Reference Tag Check Err */
316 #define NVME_CQE_SC_INT_NVM_COMPARE 0x85 /* Compare Failure */
317 #define NVME_CQE_SC_INT_NVM_ACCESS 0x86 /* Access Denied */
320 * NVMe Asynchronous Event Request
322 #define NVME_ASYNC_TYPE_ERROR 0x0 /* Error Status */
323 #define NVME_ASYNC_TYPE_HEALTH 0x1 /* SMART/Health Status */
324 #define NVME_ASYNC_TYPE_VENDOR 0x7 /* vendor specific */
326 #define NVME_ASYNC_ERROR_INV_SQ 0x0 /* Invalid Submission Queue */
327 #define NVME_ASYNC_ERROR_INV_DBL 0x1 /* Invalid Doorbell Write */
328 #define NVME_ASYNC_ERROR_DIAGFAIL 0x2 /* Diagnostic Failure */
329 #define NVME_ASYNC_ERROR_PERSISTENT 0x3 /* Persistent Internal Error */
330 #define NVME_ASYNC_ERROR_TRANSIENT 0x4 /* Transient Internal Error */
331 #define NVME_ASYNC_ERROR_FW_LOAD 0x5 /* Firmware Image Load Error */
333 #define NVME_ASYNC_HEALTH_RELIABILITY 0x0 /* Device Reliability */
334 #define NVME_ASYNC_HEALTH_TEMPERATURE 0x1 /* Temp. Above Threshold */
335 #define NVME_ASYNC_HEALTH_SPARE 0x2 /* Spare Below Threshold */
337 typedef union {
338 struct {
339 uint8_t ae_type:3; /* Asynchronous Event Type */
340 uint8_t ae_rsvd1:5;
341 uint8_t ae_info; /* Asynchronous Event Info */
342 uint8_t ae_logpage; /* Associated Log Page */
343 uint8_t ae_rsvd2;
344 } b;
345 uint32_t r;
346 } nvme_async_event_t;
349 * NVMe Create Completion/Submission Queue
351 typedef union {
352 struct {
353 uint16_t q_qid; /* Queue Identifier */
354 uint16_t q_qsize; /* Queue Size */
355 } b;
356 uint32_t r;
357 } nvme_create_queue_dw10_t;
359 typedef union {
360 struct {
361 uint16_t cq_pc:1; /* Physically Contiguous */
362 uint16_t cq_ien:1; /* Interrupts Enabled */
363 uint16_t cq_rsvd:14;
364 uint16_t cq_iv; /* Interrupt Vector */
365 } b;
366 uint32_t r;
367 } nvme_create_cq_dw11_t;
369 typedef union {
370 struct {
371 uint16_t sq_pc:1; /* Physically Contiguous */
372 uint16_t sq_qprio:2; /* Queue Priority */
373 uint16_t sq_rsvd:13;
374 uint16_t sq_cqid; /* Completion Queue ID */
375 } b;
376 uint32_t r;
377 } nvme_create_sq_dw11_t;
380 * NVMe Identify
383 /* NVMe Identify parameters (cdw10) */
384 #define NVME_IDENTIFY_NSID 0x0 /* Identify Namespace */
385 #define NVME_IDENTIFY_CTRL 0x1 /* Identify Controller */
386 #define NVME_IDENTIFY_LIST 0x2 /* Identify List Namespaces */
390 * NVMe Abort Command
392 typedef union {
393 struct {
394 uint16_t ac_sqid; /* Submission Queue ID */
395 uint16_t ac_cid; /* Command ID */
396 } b;
397 uint32_t r;
398 } nvme_abort_cmd_t;
402 * NVMe Get Log Page
404 typedef union {
405 struct {
406 uint8_t lp_lid; /* Log Page Identifier */
407 uint8_t lp_rsvd1;
408 uint16_t lp_numd:12; /* Number of Dwords */
409 uint16_t lp_rsvd2:4;
410 } b;
411 uint32_t r;
412 } nvme_getlogpage_t;
415 #ifdef __cplusplus
417 #endif
419 #pragma pack() /* pack(1) */
421 #endif /* _NVME_REG_H */