1bb0ec6b3SJim Harris /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni *
4e9efbc13SJim Harris * Copyright (C) 2012-2013 Intel Corporation
5bb0ec6b3SJim Harris * All rights reserved.
6bb0ec6b3SJim Harris *
7bb0ec6b3SJim Harris * Redistribution and use in source and binary forms, with or without
8bb0ec6b3SJim Harris * modification, are permitted provided that the following conditions
9bb0ec6b3SJim Harris * are met:
10bb0ec6b3SJim Harris * 1. Redistributions of source code must retain the above copyright
11bb0ec6b3SJim Harris * notice, this list of conditions and the following disclaimer.
12bb0ec6b3SJim Harris * 2. Redistributions in binary form must reproduce the above copyright
13bb0ec6b3SJim Harris * notice, this list of conditions and the following disclaimer in the
14bb0ec6b3SJim Harris * documentation and/or other materials provided with the distribution.
15bb0ec6b3SJim Harris *
16bb0ec6b3SJim Harris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17bb0ec6b3SJim Harris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18bb0ec6b3SJim Harris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19bb0ec6b3SJim Harris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20bb0ec6b3SJim Harris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21bb0ec6b3SJim Harris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22bb0ec6b3SJim Harris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23bb0ec6b3SJim Harris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24bb0ec6b3SJim Harris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25bb0ec6b3SJim Harris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26bb0ec6b3SJim Harris * SUCH DAMAGE.
27bb0ec6b3SJim Harris */
28bb0ec6b3SJim Harris
29bb0ec6b3SJim Harris #ifndef __NVME_H__
30bb0ec6b3SJim Harris #define __NVME_H__
31bb0ec6b3SJim Harris
32bb0ec6b3SJim Harris #ifdef _KERNEL
33bb0ec6b3SJim Harris #include <sys/types.h>
34bb0ec6b3SJim Harris #endif
35bb0ec6b3SJim Harris
368d09e3c4SJim Harris #include <sys/param.h>
370d787e9bSWojciech Macek #include <sys/endian.h>
38*7b3ee39eSJohn Baldwin #ifndef _KERNEL
39*7b3ee39eSJohn Baldwin #include <stdbool.h>
40*7b3ee39eSJohn Baldwin #endif
41*7b3ee39eSJohn Baldwin
42*7b3ee39eSJohn Baldwin struct sbuf;
438d09e3c4SJim Harris
445076698eSJim Harris #define NVME_PASSTHROUGH_CMD _IOWR('n', 0, struct nvme_pt_command)
455076698eSJim Harris #define NVME_RESET_CONTROLLER _IO('n', 1)
46a7bf63beSAlexander Motin #define NVME_GET_NSID _IOR('n', 2, struct nvme_get_nsid)
47e32d47f3SDavid Bright #define NVME_GET_MAX_XFER_SIZE _IOR('n', 3, uint64_t)
484298ce72SJohn Baldwin #define NVME_GET_CONTROLLER_DATA _IOR('n', 4, struct nvme_controller_data)
495076698eSJim Harris
505076698eSJim Harris #define NVME_IO_TEST _IOWR('n', 100, struct nvme_io_test)
515076698eSJim Harris #define NVME_BIO_TEST _IOWR('n', 101, struct nvme_io_test)
52bb0ec6b3SJim Harris
53d86edc18SJohn Baldwin /* NB: Fabrics-specific ioctls defined in nvmf.h start at 200. */
54d86edc18SJohn Baldwin
55bb0ec6b3SJim Harris /*
564e3b2744SWarner Losh * Macros to deal with NVME revisions, as defined VS register
574e3b2744SWarner Losh */
584e3b2744SWarner Losh #define NVME_REV(x, y) (((x) << 16) | ((y) << 8))
594e3b2744SWarner Losh #define NVME_MAJOR(r) (((r) >> 16) & 0xffff)
604e3b2744SWarner Losh #define NVME_MINOR(r) (((r) >> 8) & 0xff)
614e3b2744SWarner Losh
624e3b2744SWarner Losh /*
63bb0ec6b3SJim Harris * Use to mark a command to apply to all namespaces, or to retrieve global
64bb0ec6b3SJim Harris * log pages.
65bb0ec6b3SJim Harris */
66bb0ec6b3SJim Harris #define NVME_GLOBAL_NAMESPACE_TAG ((uint32_t)0xFFFFFFFF)
67bb0ec6b3SJim Harris
68214df80aSWarner Losh /* Host memory buffer sizes are always in 4096 byte chunks */
69214df80aSWarner Losh #define NVME_HMB_UNITS 4096
70214df80aSWarner Losh
71e66c1b51SWarner Losh /* Many items are expressed in terms of power of two times MPS */
72e66c1b51SWarner Losh #define NVME_MPS_SHIFT 12
73e66c1b51SWarner Losh
741931b75eSJohn Baldwin /* Limits on queue sizes: See 4.1.3 Queue Size in NVMe 1.4b. */
751931b75eSJohn Baldwin #define NVME_MIN_ADMIN_ENTRIES 2
761931b75eSJohn Baldwin #define NVME_MAX_ADMIN_ENTRIES 4096
771931b75eSJohn Baldwin
781931b75eSJohn Baldwin #define NVME_MIN_IO_ENTRIES 2
791931b75eSJohn Baldwin #define NVME_MAX_IO_ENTRIES 65536
801931b75eSJohn Baldwin
810d787e9bSWojciech Macek /* Register field definitions */
820d787e9bSWojciech Macek #define NVME_CAP_LO_REG_MQES_SHIFT (0)
830d787e9bSWojciech Macek #define NVME_CAP_LO_REG_MQES_MASK (0xFFFF)
840d787e9bSWojciech Macek #define NVME_CAP_LO_REG_CQR_SHIFT (16)
850d787e9bSWojciech Macek #define NVME_CAP_LO_REG_CQR_MASK (0x1)
860d787e9bSWojciech Macek #define NVME_CAP_LO_REG_AMS_SHIFT (17)
870d787e9bSWojciech Macek #define NVME_CAP_LO_REG_AMS_MASK (0x3)
880d787e9bSWojciech Macek #define NVME_CAP_LO_REG_TO_SHIFT (24)
890d787e9bSWojciech Macek #define NVME_CAP_LO_REG_TO_MASK (0xFF)
9062d2cf18SWarner Losh #define NVME_CAP_LO_MQES(x) \
91479680f2SJohn Baldwin NVMEV(NVME_CAP_LO_REG_MQES, x)
9262d2cf18SWarner Losh #define NVME_CAP_LO_CQR(x) \
93479680f2SJohn Baldwin NVMEV(NVME_CAP_LO_REG_CQR, x)
9462d2cf18SWarner Losh #define NVME_CAP_LO_AMS(x) \
95479680f2SJohn Baldwin NVMEV(NVME_CAP_LO_REG_AMS, x)
9662d2cf18SWarner Losh #define NVME_CAP_LO_TO(x) \
97479680f2SJohn Baldwin NVMEV(NVME_CAP_LO_REG_TO, x)
98bb0ec6b3SJim Harris
990d787e9bSWojciech Macek #define NVME_CAP_HI_REG_DSTRD_SHIFT (0)
1000d787e9bSWojciech Macek #define NVME_CAP_HI_REG_DSTRD_MASK (0xF)
101a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_NSSRS_SHIFT (4)
102a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_NSSRS_MASK (0x1)
1036dd1985bSAlexander Motin #define NVME_CAP_HI_REG_CSS_SHIFT (5)
1046dd1985bSAlexander Motin #define NVME_CAP_HI_REG_CSS_MASK (0xff)
1050d787e9bSWojciech Macek #define NVME_CAP_HI_REG_CSS_NVM_SHIFT (5)
1060d787e9bSWojciech Macek #define NVME_CAP_HI_REG_CSS_NVM_MASK (0x1)
107a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_BPS_SHIFT (13)
108a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_BPS_MASK (0x1)
109b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_CPS_SHIFT (14)
110b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_CPS_MASK (0x3)
1110d787e9bSWojciech Macek #define NVME_CAP_HI_REG_MPSMIN_SHIFT (16)
1120d787e9bSWojciech Macek #define NVME_CAP_HI_REG_MPSMIN_MASK (0xF)
1130d787e9bSWojciech Macek #define NVME_CAP_HI_REG_MPSMAX_SHIFT (20)
1140d787e9bSWojciech Macek #define NVME_CAP_HI_REG_MPSMAX_MASK (0xF)
115a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_PMRS_SHIFT (24)
116a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_PMRS_MASK (0x1)
117a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_CMBS_SHIFT (25)
118a6d222ebSAlexander Motin #define NVME_CAP_HI_REG_CMBS_MASK (0x1)
119b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_NSSS_SHIFT (26)
120b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_NSSS_MASK (0x1)
121b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_CRWMS_SHIFT (27)
122b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_CRWMS_MASK (0x1)
123b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_CRIMS_SHIFT (28)
124b46c7b1eSAlexander Motin #define NVME_CAP_HI_REG_CRIMS_MASK (0x1)
12562d2cf18SWarner Losh #define NVME_CAP_HI_DSTRD(x) \
126479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_DSTRD, x)
127c44441f8SAlexander Motin #define NVME_CAP_HI_NSSRS(x) \
128479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_NSSRS, x)
129c44441f8SAlexander Motin #define NVME_CAP_HI_CSS(x) \
130479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_CSS, x)
1316dd1985bSAlexander Motin #define NVME_CAP_HI_CSS_NVM(x) \
132479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_CSS_NVM, x)
133c44441f8SAlexander Motin #define NVME_CAP_HI_BPS(x) \
134479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_BPS, x)
135b46c7b1eSAlexander Motin #define NVME_CAP_HI_CPS(x) \
136479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_CPS, x)
13762d2cf18SWarner Losh #define NVME_CAP_HI_MPSMIN(x) \
138479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_MPSMIN, x)
13962d2cf18SWarner Losh #define NVME_CAP_HI_MPSMAX(x) \
140479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_MPSMAX, x)
141c44441f8SAlexander Motin #define NVME_CAP_HI_PMRS(x) \
142479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_PMRS, x)
143c44441f8SAlexander Motin #define NVME_CAP_HI_CMBS(x) \
144479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_CMBS, x)
145b46c7b1eSAlexander Motin #define NVME_CAP_HI_NSSS(x) \
146479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_NSSS, x)
147b46c7b1eSAlexander Motin #define NVME_CAP_HI_CRWMS(x) \
148479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_CRWMS, x)
149b46c7b1eSAlexander Motin #define NVME_CAP_HI_CRIMS(x) \
150479680f2SJohn Baldwin NVMEV(NVME_CAP_HI_REG_CRIMS, x)
151bb0ec6b3SJim Harris
1520d787e9bSWojciech Macek #define NVME_CC_REG_EN_SHIFT (0)
1530d787e9bSWojciech Macek #define NVME_CC_REG_EN_MASK (0x1)
1540d787e9bSWojciech Macek #define NVME_CC_REG_CSS_SHIFT (4)
1550d787e9bSWojciech Macek #define NVME_CC_REG_CSS_MASK (0x7)
1560d787e9bSWojciech Macek #define NVME_CC_REG_MPS_SHIFT (7)
1570d787e9bSWojciech Macek #define NVME_CC_REG_MPS_MASK (0xF)
1580d787e9bSWojciech Macek #define NVME_CC_REG_AMS_SHIFT (11)
1590d787e9bSWojciech Macek #define NVME_CC_REG_AMS_MASK (0x7)
1600d787e9bSWojciech Macek #define NVME_CC_REG_SHN_SHIFT (14)
1610d787e9bSWojciech Macek #define NVME_CC_REG_SHN_MASK (0x3)
1620d787e9bSWojciech Macek #define NVME_CC_REG_IOSQES_SHIFT (16)
1630d787e9bSWojciech Macek #define NVME_CC_REG_IOSQES_MASK (0xF)
1640d787e9bSWojciech Macek #define NVME_CC_REG_IOCQES_SHIFT (20)
1650d787e9bSWojciech Macek #define NVME_CC_REG_IOCQES_MASK (0xF)
166b46c7b1eSAlexander Motin #define NVME_CC_REG_CRIME_SHIFT (24)
167b46c7b1eSAlexander Motin #define NVME_CC_REG_CRIME_MASK (0x1)
168bb0ec6b3SJim Harris
1690d787e9bSWojciech Macek #define NVME_CSTS_REG_RDY_SHIFT (0)
1700d787e9bSWojciech Macek #define NVME_CSTS_REG_RDY_MASK (0x1)
1710d787e9bSWojciech Macek #define NVME_CSTS_REG_CFS_SHIFT (1)
1720d787e9bSWojciech Macek #define NVME_CSTS_REG_CFS_MASK (0x1)
1730d787e9bSWojciech Macek #define NVME_CSTS_REG_SHST_SHIFT (2)
1740d787e9bSWojciech Macek #define NVME_CSTS_REG_SHST_MASK (0x3)
175a6d222ebSAlexander Motin #define NVME_CSTS_REG_NVSRO_SHIFT (4)
176a6d222ebSAlexander Motin #define NVME_CSTS_REG_NVSRO_MASK (0x1)
177a6d222ebSAlexander Motin #define NVME_CSTS_REG_PP_SHIFT (5)
178a6d222ebSAlexander Motin #define NVME_CSTS_REG_PP_MASK (0x1)
179b46c7b1eSAlexander Motin #define NVME_CSTS_REG_ST_SHIFT (6)
180b46c7b1eSAlexander Motin #define NVME_CSTS_REG_ST_MASK (0x1)
181bb0ec6b3SJim Harris
182479680f2SJohn Baldwin #define NVME_CSTS_GET_SHST(csts) \
183479680f2SJohn Baldwin NVMEV(NVME_CSTS_REG_SHST, csts)
184bb0ec6b3SJim Harris
1850d787e9bSWojciech Macek #define NVME_AQA_REG_ASQS_SHIFT (0)
1860d787e9bSWojciech Macek #define NVME_AQA_REG_ASQS_MASK (0xFFF)
1870d787e9bSWojciech Macek #define NVME_AQA_REG_ACQS_SHIFT (16)
1880d787e9bSWojciech Macek #define NVME_AQA_REG_ACQS_MASK (0xFFF)
1890c26c199SWarner Losh
1900bed3eabSAlexander Motin #define NVME_PMRCAP_REG_RDS_SHIFT (3)
1910bed3eabSAlexander Motin #define NVME_PMRCAP_REG_RDS_MASK (0x1)
1920bed3eabSAlexander Motin #define NVME_PMRCAP_REG_WDS_SHIFT (4)
1930bed3eabSAlexander Motin #define NVME_PMRCAP_REG_WDS_MASK (0x1)
1940bed3eabSAlexander Motin #define NVME_PMRCAP_REG_BIR_SHIFT (5)
1950bed3eabSAlexander Motin #define NVME_PMRCAP_REG_BIR_MASK (0x7)
1960bed3eabSAlexander Motin #define NVME_PMRCAP_REG_PMRTU_SHIFT (8)
1970bed3eabSAlexander Motin #define NVME_PMRCAP_REG_PMRTU_MASK (0x3)
1980bed3eabSAlexander Motin #define NVME_PMRCAP_REG_PMRWBM_SHIFT (10)
1990bed3eabSAlexander Motin #define NVME_PMRCAP_REG_PMRWBM_MASK (0xf)
2000bed3eabSAlexander Motin #define NVME_PMRCAP_REG_PMRTO_SHIFT (16)
2010bed3eabSAlexander Motin #define NVME_PMRCAP_REG_PMRTO_MASK (0xff)
2020bed3eabSAlexander Motin #define NVME_PMRCAP_REG_CMSS_SHIFT (24)
2030bed3eabSAlexander Motin #define NVME_PMRCAP_REG_CMSS_MASK (0x1)
2040bed3eabSAlexander Motin
2050bed3eabSAlexander Motin #define NVME_PMRCAP_RDS(x) \
206479680f2SJohn Baldwin NVMEV(NVME_PMRCAP_REG_RDS, x)
2070bed3eabSAlexander Motin #define NVME_PMRCAP_WDS(x) \
208479680f2SJohn Baldwin NVMEV(NVME_PMRCAP_REG_WDS, x)
2090bed3eabSAlexander Motin #define NVME_PMRCAP_BIR(x) \
210479680f2SJohn Baldwin NVMEV(NVME_PMRCAP_REG_BIR, x)
2110bed3eabSAlexander Motin #define NVME_PMRCAP_PMRTU(x) \
212479680f2SJohn Baldwin NVMEV(NVME_PMRCAP_REG_PMRTU, x)
2130bed3eabSAlexander Motin #define NVME_PMRCAP_PMRWBM(x) \
214479680f2SJohn Baldwin NVMEV(NVME_PMRCAP_REG_PMRWBM, x)
2150bed3eabSAlexander Motin #define NVME_PMRCAP_PMRTO(x) \
216479680f2SJohn Baldwin NVMEV(NVME_PMRCAP_REG_PMRTO, x)
2170bed3eabSAlexander Motin #define NVME_PMRCAP_CMSS(x) \
218479680f2SJohn Baldwin NVMEV(NVME_PMRCAP_REG_CMSS, x)
2190bed3eabSAlexander Motin
2200d787e9bSWojciech Macek /* Command field definitions */
221bb0ec6b3SJim Harris
2225e3e4442SJohn Baldwin enum nvme_fuse {
2235e3e4442SJohn Baldwin NVME_FUSE_NORMAL = 0x0,
2245e3e4442SJohn Baldwin NVME_FUSE_FIRST = 0x1,
2255e3e4442SJohn Baldwin NVME_FUSE_SECOND = 0x2
2265e3e4442SJohn Baldwin };
227b8cb8dd3SJohn Baldwin #define NVME_CMD_FUSE_SHIFT (0)
2280d787e9bSWojciech Macek #define NVME_CMD_FUSE_MASK (0x3)
229bb0ec6b3SJim Harris
230b8cb8dd3SJohn Baldwin enum nvme_psdt {
231b8cb8dd3SJohn Baldwin NVME_PSDT_PRP = 0x0,
232b8cb8dd3SJohn Baldwin NVME_PSDT_SGL = 0x1,
233b8cb8dd3SJohn Baldwin NVME_PSDT_SGL_MPTR = 0x2
234b8cb8dd3SJohn Baldwin };
235b8cb8dd3SJohn Baldwin #define NVME_CMD_PSDT_SHIFT (6)
236b8cb8dd3SJohn Baldwin #define NVME_CMD_PSDT_MASK (0x3)
237b8cb8dd3SJohn Baldwin
238b8cb8dd3SJohn Baldwin
2390d787e9bSWojciech Macek #define NVME_STATUS_P_SHIFT (0)
2400d787e9bSWojciech Macek #define NVME_STATUS_P_MASK (0x1)
2410d787e9bSWojciech Macek #define NVME_STATUS_SC_SHIFT (1)
2420d787e9bSWojciech Macek #define NVME_STATUS_SC_MASK (0xFF)
2430d787e9bSWojciech Macek #define NVME_STATUS_SCT_SHIFT (9)
2440d787e9bSWojciech Macek #define NVME_STATUS_SCT_MASK (0x7)
245a6d222ebSAlexander Motin #define NVME_STATUS_CRD_SHIFT (12)
246a6d222ebSAlexander Motin #define NVME_STATUS_CRD_MASK (0x3)
2470d787e9bSWojciech Macek #define NVME_STATUS_M_SHIFT (14)
2480d787e9bSWojciech Macek #define NVME_STATUS_M_MASK (0x1)
2490d787e9bSWojciech Macek #define NVME_STATUS_DNR_SHIFT (15)
2500d787e9bSWojciech Macek #define NVME_STATUS_DNR_MASK (0x1)
251bb0ec6b3SJim Harris
252479680f2SJohn Baldwin #define NVME_STATUS_GET_P(st) \
253479680f2SJohn Baldwin NVMEV(NVME_STATUS_P, st)
254479680f2SJohn Baldwin #define NVME_STATUS_GET_SC(st) \
255479680f2SJohn Baldwin NVMEV(NVME_STATUS_SC, st)
256479680f2SJohn Baldwin #define NVME_STATUS_GET_SCT(st) \
257479680f2SJohn Baldwin NVMEV(NVME_STATUS_SCT, st)
258479680f2SJohn Baldwin #define NVME_STATUS_GET_CRD(st) \
259479680f2SJohn Baldwin NVMEV(NVME_STATUS_CRD, st)
260479680f2SJohn Baldwin #define NVME_STATUS_GET_M(st) \
261479680f2SJohn Baldwin NVMEV(NVME_STATUS_M, st)
262479680f2SJohn Baldwin #define NVME_STATUS_GET_DNR(st) \
263479680f2SJohn Baldwin NVMEV(NVME_STATUS_DNR, st)
264bb0ec6b3SJim Harris
2650d787e9bSWojciech Macek #define NVME_PWR_ST_MPS_SHIFT (0)
2660d787e9bSWojciech Macek #define NVME_PWR_ST_MPS_MASK (0x1)
2670d787e9bSWojciech Macek #define NVME_PWR_ST_NOPS_SHIFT (1)
2680d787e9bSWojciech Macek #define NVME_PWR_ST_NOPS_MASK (0x1)
2690d787e9bSWojciech Macek #define NVME_PWR_ST_RRT_SHIFT (0)
2700d787e9bSWojciech Macek #define NVME_PWR_ST_RRT_MASK (0x1F)
2710d787e9bSWojciech Macek #define NVME_PWR_ST_RRL_SHIFT (0)
2720d787e9bSWojciech Macek #define NVME_PWR_ST_RRL_MASK (0x1F)
2730d787e9bSWojciech Macek #define NVME_PWR_ST_RWT_SHIFT (0)
2740d787e9bSWojciech Macek #define NVME_PWR_ST_RWT_MASK (0x1F)
2750d787e9bSWojciech Macek #define NVME_PWR_ST_RWL_SHIFT (0)
2760d787e9bSWojciech Macek #define NVME_PWR_ST_RWL_MASK (0x1F)
2770d787e9bSWojciech Macek #define NVME_PWR_ST_IPS_SHIFT (6)
2780d787e9bSWojciech Macek #define NVME_PWR_ST_IPS_MASK (0x3)
2790d787e9bSWojciech Macek #define NVME_PWR_ST_APW_SHIFT (0)
2800d787e9bSWojciech Macek #define NVME_PWR_ST_APW_MASK (0x7)
2810d787e9bSWojciech Macek #define NVME_PWR_ST_APS_SHIFT (6)
2820d787e9bSWojciech Macek #define NVME_PWR_ST_APS_MASK (0x3)
283bb0ec6b3SJim Harris
2843fa5467aSAlexander Motin /** Controller Multi-path I/O and Namespace Sharing Capabilities */
2853fa5467aSAlexander Motin /* More then one port */
2863fa5467aSAlexander Motin #define NVME_CTRLR_DATA_MIC_MPORTS_SHIFT (0)
2873fa5467aSAlexander Motin #define NVME_CTRLR_DATA_MIC_MPORTS_MASK (0x1)
2883fa5467aSAlexander Motin /* More then one controller */
2893fa5467aSAlexander Motin #define NVME_CTRLR_DATA_MIC_MCTRLRS_SHIFT (1)
2903fa5467aSAlexander Motin #define NVME_CTRLR_DATA_MIC_MCTRLRS_MASK (0x1)
2913fa5467aSAlexander Motin /* SR-IOV Virtual Function */
2923fa5467aSAlexander Motin #define NVME_CTRLR_DATA_MIC_SRIOVVF_SHIFT (2)
2933fa5467aSAlexander Motin #define NVME_CTRLR_DATA_MIC_SRIOVVF_MASK (0x1)
2948de2d8c0SAlexander Motin /* Asymmetric Namespace Access Reporting */
2958de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_MIC_ANAR_SHIFT (3)
2968de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_MIC_ANAR_MASK (0x1)
2973fa5467aSAlexander Motin
298e71afa12SChuck Tuffli /** OAES - Optional Asynchronous Events Supported */
299e71afa12SChuck Tuffli /* supports Namespace Attribute Notices event */
300e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_NS_ATTR_SHIFT (8)
301e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_NS_ATTR_MASK (0x1)
302e71afa12SChuck Tuffli /* supports Firmware Activation Notices event */
303e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_FW_ACTIVATE_SHIFT (9)
304e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_FW_ACTIVATE_MASK (0x1)
305e71afa12SChuck Tuffli /* supports Asymmetric Namespace Access Change Notices event */
306e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_ASYM_NS_CHANGE_SHIFT (11)
307e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_ASYM_NS_CHANGE_MASK (0x1)
308e71afa12SChuck Tuffli /* supports Predictable Latency Event Aggregate Log Change Notices event */
309e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_PREDICT_LATENCY_SHIFT (12)
310e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_PREDICT_LATENCY_MASK (0x1)
311e71afa12SChuck Tuffli /* supports LBA Status Information Notices event */
312e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_LBA_STATUS_SHIFT (13)
313e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_LBA_STATUS_MASK (0x1)
314e71afa12SChuck Tuffli /* supports Endurance Group Event Aggregate Log Page Changes Notices event */
315e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_ENDURANCE_GROUP_SHIFT (14)
316e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_ENDURANCE_GROUP_MASK (0x1)
317e71afa12SChuck Tuffli /* supports Normal NVM Subsystem Shutdown event */
318e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_NORMAL_SHUTDOWN_SHIFT (15)
319e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_NORMAL_SHUTDOWN_MASK (0x1)
320e71afa12SChuck Tuffli /* supports Zone Descriptor Changed Notices event */
321e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_ZONE_DESC_CHANGE_SHIFT (27)
322e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_ZONE_DESC_CHANGE_MASK (0x1)
323e71afa12SChuck Tuffli /* supports Discovery Log Page Change Notification event */
324e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_LOG_PAGE_CHANGE_SHIFT (31)
325e71afa12SChuck Tuffli #define NVME_CTRLR_DATA_OAES_LOG_PAGE_CHANGE_MASK (0x1)
326e71afa12SChuck Tuffli
3277fa8adb8SJohn Baldwin /** CTRATT - Controller Attributes */
3287fa8adb8SJohn Baldwin /* supports 128-bit Host Identifier */
3297fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_128BIT_HOSTID_SHIFT (0)
3307fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_128BIT_HOSTID_MASK (0x1)
3317fa8adb8SJohn Baldwin /* supports Non-Operational Power State Permissive Mode */
3327fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_NONOP_POWER_STATE_SHIFT (1)
3337fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_NONOP_POWER_STATE_MASK (0x1)
3347fa8adb8SJohn Baldwin /* supports NVM Sets */
3357fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_NVM_SETS_SHIFT (2)
3367fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_NVM_SETS_MASK (0x1)
3377fa8adb8SJohn Baldwin /* supports Read Recovery Levels */
3387fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_READ_RECOVERY_LVLS_SHIFT (3)
3397fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_READ_RECOVERY_LVLS_MASK (0x1)
3407fa8adb8SJohn Baldwin /* supports Endurance Groups */
3417fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_ENDURANCE_GROUPS_SHIFT (4)
3427fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_ENDURANCE_GROUPS_MASK (0x1)
3437fa8adb8SJohn Baldwin /* supports Predictable Latency Mode */
3447fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_PREDICTABLE_LATENCY_SHIFT (5)
3457fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_PREDICTABLE_LATENCY_MASK (0x1)
3467fa8adb8SJohn Baldwin /* supports Traffic Based Keep Alive Support */
3477fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_TBKAS_SHIFT (6)
3487fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_TBKAS_MASK (0x1)
3497fa8adb8SJohn Baldwin /* supports Namespace Granularity */
3507fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_NAMESPACE_GRANULARITY_SHIFT (7)
3517fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_NAMESPACE_GRANULARITY_MASK (0x1)
3527fa8adb8SJohn Baldwin /* supports SQ Associations */
3537fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_SQ_ASSOCIATIONS_SHIFT (8)
3547fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_SQ_ASSOCIATIONS_MASK (0x1)
3557fa8adb8SJohn Baldwin /* supports UUID List */
3567fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_UUID_LIST_SHIFT (9)
3577fa8adb8SJohn Baldwin #define NVME_CTRLR_DATA_CTRATT_UUID_LIST_MASK (0x1)
3587fa8adb8SJohn Baldwin
3590d787e9bSWojciech Macek /** OACS - optional admin command support */
3600d787e9bSWojciech Macek /* supports security send/receive commands */
3610d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_SECURITY_SHIFT (0)
3620d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_SECURITY_MASK (0x1)
3630d787e9bSWojciech Macek /* supports format nvm command */
3640d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_FORMAT_SHIFT (1)
3650d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_FORMAT_MASK (0x1)
3660d787e9bSWojciech Macek /* supports firmware activate/download commands */
3670d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_FIRMWARE_SHIFT (2)
3680d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_FIRMWARE_MASK (0x1)
3690d787e9bSWojciech Macek /* supports namespace management commands */
3700d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT (3)
3710d787e9bSWojciech Macek #define NVME_CTRLR_DATA_OACS_NSMGMT_MASK (0x1)
3723fa5467aSAlexander Motin /* supports Device Self-test command */
3733fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_SELFTEST_SHIFT (4)
3743fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_SELFTEST_MASK (0x1)
3753fa5467aSAlexander Motin /* supports Directives */
3763fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_DIRECTIVES_SHIFT (5)
3773fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_DIRECTIVES_MASK (0x1)
3783fa5467aSAlexander Motin /* supports NVMe-MI Send/Receive */
3793fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_NVMEMI_SHIFT (6)
3803fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_NVMEMI_MASK (0x1)
3813fa5467aSAlexander Motin /* supports Virtualization Management */
3823fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_VM_SHIFT (7)
3833fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_VM_MASK (0x1)
3843fa5467aSAlexander Motin /* supports Doorbell Buffer Config */
3853fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_DBBUFFER_SHIFT (8)
3863fa5467aSAlexander Motin #define NVME_CTRLR_DATA_OACS_DBBUFFER_MASK (0x1)
3878de2d8c0SAlexander Motin /* supports Get LBA Status */
3888de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_OACS_GETLBA_SHIFT (9)
3898de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_OACS_GETLBA_MASK (0x1)
390bb0ec6b3SJim Harris
3910d787e9bSWojciech Macek /** firmware updates */
3920d787e9bSWojciech Macek /* first slot is read-only */
3930d787e9bSWojciech Macek #define NVME_CTRLR_DATA_FRMW_SLOT1_RO_SHIFT (0)
3940d787e9bSWojciech Macek #define NVME_CTRLR_DATA_FRMW_SLOT1_RO_MASK (0x1)
3950d787e9bSWojciech Macek /* number of firmware slots */
3960d787e9bSWojciech Macek #define NVME_CTRLR_DATA_FRMW_NUM_SLOTS_SHIFT (1)
3970d787e9bSWojciech Macek #define NVME_CTRLR_DATA_FRMW_NUM_SLOTS_MASK (0x7)
3988de2d8c0SAlexander Motin /* firmware activation without reset */
3998de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_FRMW_ACT_WO_RESET_SHIFT (4)
4008de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_FRMW_ACT_WO_RESET_MASK (0x1)
4010c26c199SWarner Losh
4020d787e9bSWojciech Macek /** log page attributes */
4030d787e9bSWojciech Macek /* per namespace smart/health log page */
4040d787e9bSWojciech Macek #define NVME_CTRLR_DATA_LPA_NS_SMART_SHIFT (0)
4050d787e9bSWojciech Macek #define NVME_CTRLR_DATA_LPA_NS_SMART_MASK (0x1)
4060b8f21e8SWarner Losh /* Commands Supported and Effects log page */
4070b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_CMD_EFFECTS_SHIFT (1)
4080b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_CMD_EFFECTS_MASK (0x1)
409cbda1886SJohn Baldwin /* extended data for Get Log Page command */
410cbda1886SJohn Baldwin #define NVME_CTRLR_DATA_LPA_EXT_DATA_SHIFT (2)
411cbda1886SJohn Baldwin #define NVME_CTRLR_DATA_LPA_EXT_DATA_MASK (0x1)
4120b8f21e8SWarner Losh /* telemetry */
4130b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_TELEMETRY_SHIFT (3)
4140b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_TELEMETRY_MASK (0x1)
4150b8f21e8SWarner Losh /* persistent event */
4160b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_PERSISTENT_EVENT_SHIFT (4)
4170b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_PERSISTENT_EVENT_MASK (0x1)
4180b8f21e8SWarner Losh /* Supported log pages, etc */
4190b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_LOG_PAGES_PAGE_SHIFT (5)
4200b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_LOG_PAGES_PAGE_MASK (0x1)
4210b8f21e8SWarner Losh /* Data Area 4 for Telemetry */
4220b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_DA4_TELEMETRY_SHIFT (6)
4230b8f21e8SWarner Losh #define NVME_CTRLR_DATA_LPA_DA4_TELEMETRY_MASK (0x1)
424bb0ec6b3SJim Harris
4250d787e9bSWojciech Macek /** AVSCC - admin vendor specific command configuration */
4260d787e9bSWojciech Macek /* admin vendor specific commands use spec format */
4270d787e9bSWojciech Macek #define NVME_CTRLR_DATA_AVSCC_SPEC_FORMAT_SHIFT (0)
4280d787e9bSWojciech Macek #define NVME_CTRLR_DATA_AVSCC_SPEC_FORMAT_MASK (0x1)
429bb0ec6b3SJim Harris
4300d787e9bSWojciech Macek /** Autonomous Power State Transition Attributes */
4310d787e9bSWojciech Macek /* Autonomous Power State Transitions supported */
4320d787e9bSWojciech Macek #define NVME_CTRLR_DATA_APSTA_APST_SUPP_SHIFT (0)
4330d787e9bSWojciech Macek #define NVME_CTRLR_DATA_APSTA_APST_SUPP_MASK (0x1)
434bb0ec6b3SJim Harris
4358de2d8c0SAlexander Motin /** Sanitize Capabilities */
4368de2d8c0SAlexander Motin /* Crypto Erase Support */
4378de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_CES_SHIFT (0)
4388de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_CES_MASK (0x1)
4398de2d8c0SAlexander Motin /* Block Erase Support */
4408de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_BES_SHIFT (1)
4418de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_BES_MASK (0x1)
4428de2d8c0SAlexander Motin /* Overwrite Support */
4438de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_OWS_SHIFT (2)
4448de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_OWS_MASK (0x1)
4458de2d8c0SAlexander Motin /* No-Deallocate Inhibited */
4468de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_NDI_SHIFT (29)
4478de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_NDI_MASK (0x1)
4488de2d8c0SAlexander Motin /* No-Deallocate Modifies Media After Sanitize */
4498de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_NODMMAS_SHIFT (30)
4508de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_NODMMAS_MASK (0x3)
4518de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_NODMMAS_UNDEF (0)
4528de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_NODMMAS_NO (1)
4538de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_SANICAP_NODMMAS_YES (2)
4548de2d8c0SAlexander Motin
4550d787e9bSWojciech Macek /** submission queue entry size */
4560d787e9bSWojciech Macek #define NVME_CTRLR_DATA_SQES_MIN_SHIFT (0)
4570d787e9bSWojciech Macek #define NVME_CTRLR_DATA_SQES_MIN_MASK (0xF)
4580d787e9bSWojciech Macek #define NVME_CTRLR_DATA_SQES_MAX_SHIFT (4)
4590d787e9bSWojciech Macek #define NVME_CTRLR_DATA_SQES_MAX_MASK (0xF)
460bb0ec6b3SJim Harris
4610d787e9bSWojciech Macek /** completion queue entry size */
4620d787e9bSWojciech Macek #define NVME_CTRLR_DATA_CQES_MIN_SHIFT (0)
4630d787e9bSWojciech Macek #define NVME_CTRLR_DATA_CQES_MIN_MASK (0xF)
4640d787e9bSWojciech Macek #define NVME_CTRLR_DATA_CQES_MAX_SHIFT (4)
4650d787e9bSWojciech Macek #define NVME_CTRLR_DATA_CQES_MAX_MASK (0xF)
466bb0ec6b3SJim Harris
4670d787e9bSWojciech Macek /** optional nvm command support */
4680d787e9bSWojciech Macek #define NVME_CTRLR_DATA_ONCS_COMPARE_SHIFT (0)
4690d787e9bSWojciech Macek #define NVME_CTRLR_DATA_ONCS_COMPARE_MASK (0x1)
4700d787e9bSWojciech Macek #define NVME_CTRLR_DATA_ONCS_WRITE_UNC_SHIFT (1)
4710d787e9bSWojciech Macek #define NVME_CTRLR_DATA_ONCS_WRITE_UNC_MASK (0x1)
4720d787e9bSWojciech Macek #define NVME_CTRLR_DATA_ONCS_DSM_SHIFT (2)
4730d787e9bSWojciech Macek #define NVME_CTRLR_DATA_ONCS_DSM_MASK (0x1)
4743fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_WRZERO_SHIFT (3)
4753fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_WRZERO_MASK (0x1)
4763fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_SAVEFEAT_SHIFT (4)
4773fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_SAVEFEAT_MASK (0x1)
4783fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_RESERV_SHIFT (5)
4793fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_RESERV_MASK (0x1)
4803fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_TIMESTAMP_SHIFT (6)
4813fa5467aSAlexander Motin #define NVME_CTRLR_DATA_ONCS_TIMESTAMP_MASK (0x1)
4828de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_ONCS_VERIFY_SHIFT (7)
4838de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_ONCS_VERIFY_MASK (0x1)
484bb0ec6b3SJim Harris
48501c1be35SAlexander Motin /** Fused Operation Support */
48601c1be35SAlexander Motin #define NVME_CTRLR_DATA_FUSES_CNW_SHIFT (0)
48701c1be35SAlexander Motin #define NVME_CTRLR_DATA_FUSES_CNW_MASK (0x1)
48801c1be35SAlexander Motin
48901c1be35SAlexander Motin /** Format NVM Attributes */
49001c1be35SAlexander Motin #define NVME_CTRLR_DATA_FNA_FORMAT_ALL_SHIFT (0)
49101c1be35SAlexander Motin #define NVME_CTRLR_DATA_FNA_FORMAT_ALL_MASK (0x1)
49201c1be35SAlexander Motin #define NVME_CTRLR_DATA_FNA_ERASE_ALL_SHIFT (1)
49301c1be35SAlexander Motin #define NVME_CTRLR_DATA_FNA_ERASE_ALL_MASK (0x1)
49401c1be35SAlexander Motin #define NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_SHIFT (2)
49501c1be35SAlexander Motin #define NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_MASK (0x1)
49601c1be35SAlexander Motin
4970d787e9bSWojciech Macek /** volatile write cache */
4988de2d8c0SAlexander Motin /* volatile write cache present */
4990d787e9bSWojciech Macek #define NVME_CTRLR_DATA_VWC_PRESENT_SHIFT (0)
5000d787e9bSWojciech Macek #define NVME_CTRLR_DATA_VWC_PRESENT_MASK (0x1)
5018de2d8c0SAlexander Motin /* flush all namespaces supported */
5028de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_VWC_ALL_SHIFT (1)
5038de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_VWC_ALL_MASK (0x3)
5048de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_VWC_ALL_UNKNOWN (0)
5058de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_VWC_ALL_NO (2)
5068de2d8c0SAlexander Motin #define NVME_CTRLR_DATA_VWC_ALL_YES (3)
507bb0ec6b3SJim Harris
508f21a54d1SJohn Baldwin /** SGL Support */
509f21a54d1SJohn Baldwin /* NVM command set SGL support */
510f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_NVM_COMMAND_SET_SHIFT (0)
511f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_NVM_COMMAND_SET_MASK (0x3)
512f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_KEYED_DATA_BLOCK_SHIFT (2)
513f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_KEYED_DATA_BLOCK_MASK (0x1)
514f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_BIT_BUCKET_SHIFT (16)
515f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_BIT_BUCKET_MASK (0x1)
516f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_CONTIG_MPTR_SHIFT (17)
517f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_CONTIG_MPTR_MASK (0x1)
518f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_OVERSIZED_SHIFT (18)
519f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_OVERSIZED_MASK (0x1)
520f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_MPTR_SGL_SHIFT (19)
521f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_MPTR_SGL_MASK (0x1)
522f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_ADDRESS_AS_OFFSET_SHIFT (20)
523f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_ADDRESS_AS_OFFSET_MASK (0x1)
524f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_TRANSPORT_DATA_BLOCK_SHIFT (21)
525f21a54d1SJohn Baldwin #define NVME_CTRLR_DATA_SGLS_TRANSPORT_DATA_BLOCK_MASK (0x1)
526f21a54d1SJohn Baldwin
5270d787e9bSWojciech Macek /** namespace features */
5280d787e9bSWojciech Macek /* thin provisioning */
5290d787e9bSWojciech Macek #define NVME_NS_DATA_NSFEAT_THIN_PROV_SHIFT (0)
5300d787e9bSWojciech Macek #define NVME_NS_DATA_NSFEAT_THIN_PROV_MASK (0x1)
5313fa5467aSAlexander Motin /* NAWUN, NAWUPF, and NACWU fields are valid */
5323fa5467aSAlexander Motin #define NVME_NS_DATA_NSFEAT_NA_FIELDS_SHIFT (1)
5333fa5467aSAlexander Motin #define NVME_NS_DATA_NSFEAT_NA_FIELDS_MASK (0x1)
5343fa5467aSAlexander Motin /* Deallocated or Unwritten Logical Block errors supported */
5353fa5467aSAlexander Motin #define NVME_NS_DATA_NSFEAT_DEALLOC_SHIFT (2)
5363fa5467aSAlexander Motin #define NVME_NS_DATA_NSFEAT_DEALLOC_MASK (0x1)
5373fa5467aSAlexander Motin /* NGUID and EUI64 fields are not reusable */
5383fa5467aSAlexander Motin #define NVME_NS_DATA_NSFEAT_NO_ID_REUSE_SHIFT (3)
5393fa5467aSAlexander Motin #define NVME_NS_DATA_NSFEAT_NO_ID_REUSE_MASK (0x1)
5408de2d8c0SAlexander Motin /* NPWG, NPWA, NPDG, NPDA, and NOWS are valid */
5418de2d8c0SAlexander Motin #define NVME_NS_DATA_NSFEAT_NPVALID_SHIFT (4)
5428de2d8c0SAlexander Motin #define NVME_NS_DATA_NSFEAT_NPVALID_MASK (0x1)
543bb0ec6b3SJim Harris
5440d787e9bSWojciech Macek /** formatted lba size */
5450d787e9bSWojciech Macek #define NVME_NS_DATA_FLBAS_FORMAT_SHIFT (0)
5460d787e9bSWojciech Macek #define NVME_NS_DATA_FLBAS_FORMAT_MASK (0xF)
5470d787e9bSWojciech Macek #define NVME_NS_DATA_FLBAS_EXTENDED_SHIFT (4)
5480d787e9bSWojciech Macek #define NVME_NS_DATA_FLBAS_EXTENDED_MASK (0x1)
549bb0ec6b3SJim Harris
5500d787e9bSWojciech Macek /** metadata capabilities */
5510d787e9bSWojciech Macek /* metadata can be transferred as part of data prp list */
5520d787e9bSWojciech Macek #define NVME_NS_DATA_MC_EXTENDED_SHIFT (0)
5530d787e9bSWojciech Macek #define NVME_NS_DATA_MC_EXTENDED_MASK (0x1)
5540d787e9bSWojciech Macek /* metadata can be transferred with separate metadata pointer */
5550d787e9bSWojciech Macek #define NVME_NS_DATA_MC_POINTER_SHIFT (1)
5560d787e9bSWojciech Macek #define NVME_NS_DATA_MC_POINTER_MASK (0x1)
5570c26c199SWarner Losh
5580d787e9bSWojciech Macek /** end-to-end data protection capabilities */
5590d787e9bSWojciech Macek /* protection information type 1 */
5600d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_PIT1_SHIFT (0)
5610d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_PIT1_MASK (0x1)
5620d787e9bSWojciech Macek /* protection information type 2 */
5630d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_PIT2_SHIFT (1)
5640d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_PIT2_MASK (0x1)
5650d787e9bSWojciech Macek /* protection information type 3 */
5660d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_PIT3_SHIFT (2)
5670d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_PIT3_MASK (0x1)
5680d787e9bSWojciech Macek /* first eight bytes of metadata */
5690d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_MD_START_SHIFT (3)
5700d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_MD_START_MASK (0x1)
5710d787e9bSWojciech Macek /* last eight bytes of metadata */
5720d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_MD_END_SHIFT (4)
5730d787e9bSWojciech Macek #define NVME_NS_DATA_DPC_MD_END_MASK (0x1)
5740d787e9bSWojciech Macek
5750d787e9bSWojciech Macek /** end-to-end data protection type settings */
5760d787e9bSWojciech Macek /* protection information type */
5770d787e9bSWojciech Macek #define NVME_NS_DATA_DPS_PIT_SHIFT (0)
5780d787e9bSWojciech Macek #define NVME_NS_DATA_DPS_PIT_MASK (0x7)
5790d787e9bSWojciech Macek /* 1 == protection info transferred at start of metadata */
5800d787e9bSWojciech Macek /* 0 == protection info transferred at end of metadata */
5810d787e9bSWojciech Macek #define NVME_NS_DATA_DPS_MD_START_SHIFT (3)
5820d787e9bSWojciech Macek #define NVME_NS_DATA_DPS_MD_START_MASK (0x1)
5830d787e9bSWojciech Macek
5843fa5467aSAlexander Motin /** Namespace Multi-path I/O and Namespace Sharing Capabilities */
5853fa5467aSAlexander Motin /* the namespace may be attached to two or more controllers */
5863fa5467aSAlexander Motin #define NVME_NS_DATA_NMIC_MAY_BE_SHARED_SHIFT (0)
5873fa5467aSAlexander Motin #define NVME_NS_DATA_NMIC_MAY_BE_SHARED_MASK (0x1)
5883fa5467aSAlexander Motin
5893fa5467aSAlexander Motin /** Reservation Capabilities */
5903fa5467aSAlexander Motin /* Persist Through Power Loss */
5913fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_PTPL_SHIFT (0)
5923fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_PTPL_MASK (0x1)
5933fa5467aSAlexander Motin /* supports the Write Exclusive */
5943fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_WR_EX_SHIFT (1)
5953fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_WR_EX_MASK (0x1)
5963fa5467aSAlexander Motin /* supports the Exclusive Access */
5973fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_EX_AC_SHIFT (2)
5983fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_EX_AC_MASK (0x1)
5993fa5467aSAlexander Motin /* supports the Write Exclusive – Registrants Only */
6003fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_WR_EX_RO_SHIFT (3)
6013fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_WR_EX_RO_MASK (0x1)
6023fa5467aSAlexander Motin /* supports the Exclusive Access - Registrants Only */
6033fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_EX_AC_RO_SHIFT (4)
6043fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_EX_AC_RO_MASK (0x1)
6053fa5467aSAlexander Motin /* supports the Write Exclusive – All Registrants */
6063fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_WR_EX_AR_SHIFT (5)
6073fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_WR_EX_AR_MASK (0x1)
6083fa5467aSAlexander Motin /* supports the Exclusive Access - All Registrants */
6093fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_EX_AC_AR_SHIFT (6)
6103fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_EX_AC_AR_MASK (0x1)
6113fa5467aSAlexander Motin /* Ignore Existing Key is used as defined in revision 1.3 or later */
6123fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_IEKEY13_SHIFT (7)
6133fa5467aSAlexander Motin #define NVME_NS_DATA_RESCAP_IEKEY13_MASK (0x1)
6143fa5467aSAlexander Motin
6153fa5467aSAlexander Motin /** Format Progress Indicator */
6163fa5467aSAlexander Motin /* percentage of the Format NVM command that remains to be completed */
6173fa5467aSAlexander Motin #define NVME_NS_DATA_FPI_PERC_SHIFT (0)
6183fa5467aSAlexander Motin #define NVME_NS_DATA_FPI_PERC_MASK (0x7f)
6193fa5467aSAlexander Motin /* namespace supports the Format Progress Indicator */
6203fa5467aSAlexander Motin #define NVME_NS_DATA_FPI_SUPP_SHIFT (7)
6213fa5467aSAlexander Motin #define NVME_NS_DATA_FPI_SUPP_MASK (0x1)
6223fa5467aSAlexander Motin
6231aed4995SAlexander Motin /** Deallocate Logical Block Features */
6241aed4995SAlexander Motin /* deallocated logical block read behavior */
6251aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_READ_SHIFT (0)
6261aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_READ_MASK (0x07)
6271aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_READ_NR (0x00)
6281aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_READ_00 (0x01)
6291aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_READ_FF (0x02)
6301aed4995SAlexander Motin /* supports the Deallocate bit in the Write Zeroes */
6311aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_DWZ_SHIFT (3)
6321aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_DWZ_MASK (0x01)
6331aed4995SAlexander Motin /* Guard field for deallocated logical blocks is set to the CRC */
6341aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_GCRC_SHIFT (4)
6351aed4995SAlexander Motin #define NVME_NS_DATA_DLFEAT_GCRC_MASK (0x01)
6361aed4995SAlexander Motin
6370d787e9bSWojciech Macek /** lba format support */
6380d787e9bSWojciech Macek /* metadata size */
6390d787e9bSWojciech Macek #define NVME_NS_DATA_LBAF_MS_SHIFT (0)
6400d787e9bSWojciech Macek #define NVME_NS_DATA_LBAF_MS_MASK (0xFFFF)
6410d787e9bSWojciech Macek /* lba data size */
6420d787e9bSWojciech Macek #define NVME_NS_DATA_LBAF_LBADS_SHIFT (16)
6430d787e9bSWojciech Macek #define NVME_NS_DATA_LBAF_LBADS_MASK (0xFF)
6440d787e9bSWojciech Macek /* relative performance */
6450d787e9bSWojciech Macek #define NVME_NS_DATA_LBAF_RP_SHIFT (24)
6460d787e9bSWojciech Macek #define NVME_NS_DATA_LBAF_RP_MASK (0x3)
6470d787e9bSWojciech Macek
6480d787e9bSWojciech Macek enum nvme_critical_warning_state {
6490d787e9bSWojciech Macek NVME_CRIT_WARN_ST_AVAILABLE_SPARE = 0x1,
6500d787e9bSWojciech Macek NVME_CRIT_WARN_ST_TEMPERATURE = 0x2,
6510d787e9bSWojciech Macek NVME_CRIT_WARN_ST_DEVICE_RELIABILITY = 0x4,
6520d787e9bSWojciech Macek NVME_CRIT_WARN_ST_READ_ONLY = 0x8,
6530d787e9bSWojciech Macek NVME_CRIT_WARN_ST_VOLATILE_MEMORY_BACKUP = 0x10,
6542a2682eeSWarner Losh NVME_CRIT_WARN_ST_PERSISTENT_MEMORY_REGION = 0x20,
6550d787e9bSWojciech Macek };
6562a2682eeSWarner Losh #define NVME_CRIT_WARN_ST_RESERVED_MASK (0xC0)
657f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_NS_ATTRIBUTE (1U << 8)
658f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_FW_ACTIVATE (1U << 9)
659f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_TELEMETRY_LOG (1U << 10)
660f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_ASYM_NS_ACC (1U << 11)
661f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_PRED_LAT_DELTA (1U << 12)
662f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_LBA_STATUS (1U << 13)
663f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_ENDURANCE_DELTA (1U << 14)
664f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_NVM_SHUTDOWN (1U << 15)
665f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_ZONE_DELTA (1U << 27)
666f68c4b47SWarner Losh #define NVME_ASYNC_EVENT_DISCOVERY_DELTA (1U << 31)
6670d787e9bSWojciech Macek
6680d787e9bSWojciech Macek /* slot for current FW */
6690d787e9bSWojciech Macek #define NVME_FIRMWARE_PAGE_AFI_SLOT_SHIFT (0)
6700d787e9bSWojciech Macek #define NVME_FIRMWARE_PAGE_AFI_SLOT_MASK (0x7)
6710d787e9bSWojciech Macek
6726c99d132SAlexander Motin /* Commands Supported and Effects */
6736c99d132SAlexander Motin #define NVME_CE_PAGE_CSUP_SHIFT (0)
6746c99d132SAlexander Motin #define NVME_CE_PAGE_CSUP_MASK (0x1)
6756c99d132SAlexander Motin #define NVME_CE_PAGE_LBCC_SHIFT (1)
6766c99d132SAlexander Motin #define NVME_CE_PAGE_LBCC_MASK (0x1)
6776c99d132SAlexander Motin #define NVME_CE_PAGE_NCC_SHIFT (2)
6786c99d132SAlexander Motin #define NVME_CE_PAGE_NCC_MASK (0x1)
6796c99d132SAlexander Motin #define NVME_CE_PAGE_NIC_SHIFT (3)
6806c99d132SAlexander Motin #define NVME_CE_PAGE_NIC_MASK (0x1)
6816c99d132SAlexander Motin #define NVME_CE_PAGE_CCC_SHIFT (4)
6826c99d132SAlexander Motin #define NVME_CE_PAGE_CCC_MASK (0x1)
6836c99d132SAlexander Motin #define NVME_CE_PAGE_CSE_SHIFT (16)
6846c99d132SAlexander Motin #define NVME_CE_PAGE_CSE_MASK (0x7)
6856c99d132SAlexander Motin #define NVME_CE_PAGE_UUID_SHIFT (19)
6866c99d132SAlexander Motin #define NVME_CE_PAGE_UUID_MASK (0x1)
6876c99d132SAlexander Motin
6886c99d132SAlexander Motin /* Sanitize Status */
6896c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_STATUS_SHIFT (0)
6906c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_STATUS_MASK (0x7)
6916c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_STATUS_NEVER (0)
6926c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_STATUS_COMPLETED (1)
6936c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_STATUS_INPROG (2)
6946c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_STATUS_FAILED (3)
6956c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_STATUS_COMPLETEDWD (4)
6966c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_PASSES_SHIFT (3)
6976c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_PASSES_MASK (0x1f)
6986c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_GDE_SHIFT (8)
6996c99d132SAlexander Motin #define NVME_SS_PAGE_SSTAT_GDE_MASK (0x1)
7006c99d132SAlexander Motin
7018ab99dbeSWanpeng Qian /* Features */
7028ab99dbeSWanpeng Qian /* Get Features */
7038ab99dbeSWanpeng Qian #define NVME_FEAT_GET_SEL_SHIFT (8)
7048ab99dbeSWanpeng Qian #define NVME_FEAT_GET_SEL_MASK (0x7)
7058ab99dbeSWanpeng Qian #define NVME_FEAT_GET_FID_SHIFT (0)
7068ab99dbeSWanpeng Qian #define NVME_FEAT_GET_FID_MASK (0xff)
7078ab99dbeSWanpeng Qian
7088ab99dbeSWanpeng Qian /* Set Features */
7098ab99dbeSWanpeng Qian #define NVME_FEAT_SET_SV_SHIFT (31)
7108ab99dbeSWanpeng Qian #define NVME_FEAT_SET_SV_MASK (0x1)
7118ab99dbeSWanpeng Qian #define NVME_FEAT_SET_FID_SHIFT (0)
7128ab99dbeSWanpeng Qian #define NVME_FEAT_SET_FID_MASK (0xff)
7138ab99dbeSWanpeng Qian
714b354bb04SJohn Baldwin /* Async Events */
715b354bb04SJohn Baldwin #define NVME_ASYNC_EVENT_TYPE_SHIFT (0)
716b354bb04SJohn Baldwin #define NVME_ASYNC_EVENT_TYPE_MASK (0x7)
717b354bb04SJohn Baldwin #define NVME_ASYNC_EVENT_INFO_SHIFT (8)
718b354bb04SJohn Baldwin #define NVME_ASYNC_EVENT_INFO_MASK (0xff)
719b354bb04SJohn Baldwin #define NVME_ASYNC_EVENT_LOG_PAGE_ID_SHIFT (16)
720b354bb04SJohn Baldwin #define NVME_ASYNC_EVENT_LOG_PAGE_ID_MASK (0xff)
721b354bb04SJohn Baldwin
722e71afa12SChuck Tuffli /* Helper macro to combine *_MASK and *_SHIFT defines */
7231dade1f2SJohn Baldwin #define NVMEM(name) (name##_MASK << name##_SHIFT)
724e71afa12SChuck Tuffli
7258ab99dbeSWanpeng Qian /* Helper macro to extract value from x */
7268ab99dbeSWanpeng Qian #define NVMEV(name, x) (((x) >> name##_SHIFT) & name##_MASK)
7278ab99dbeSWanpeng Qian
7283a477a9bSJohn Baldwin /* Helper macro to construct a field value */
7293a477a9bSJohn Baldwin #define NVMEF(name, x) (((x) & name##_MASK) << name##_SHIFT)
7303a477a9bSJohn Baldwin
7310d787e9bSWojciech Macek /* CC register SHN field values */
732bb0ec6b3SJim Harris enum shn_value {
733bb0ec6b3SJim Harris NVME_SHN_NORMAL = 0x1,
734bb0ec6b3SJim Harris NVME_SHN_ABRUPT = 0x2,
735bb0ec6b3SJim Harris };
736bb0ec6b3SJim Harris
7370d787e9bSWojciech Macek /* CSTS register SHST field values */
738bb0ec6b3SJim Harris enum shst_value {
739bb0ec6b3SJim Harris NVME_SHST_NORMAL = 0x0,
740bb0ec6b3SJim Harris NVME_SHST_OCCURRING = 0x1,
741bb0ec6b3SJim Harris NVME_SHST_COMPLETE = 0x2,
742bb0ec6b3SJim Harris };
743bb0ec6b3SJim Harris
74480a75155SWarner Losh struct nvme_registers {
745a6d222ebSAlexander Motin uint32_t cap_lo; /* controller capabilities */
7460d787e9bSWojciech Macek uint32_t cap_hi;
747bb0ec6b3SJim Harris uint32_t vs; /* version */
748bb0ec6b3SJim Harris uint32_t intms; /* interrupt mask set */
749bb0ec6b3SJim Harris uint32_t intmc; /* interrupt mask clear */
750a6d222ebSAlexander Motin uint32_t cc; /* controller configuration */
751bb0ec6b3SJim Harris uint32_t reserved1;
752a6d222ebSAlexander Motin uint32_t csts; /* controller status */
753a6d222ebSAlexander Motin uint32_t nssr; /* NVM Subsystem Reset */
754a6d222ebSAlexander Motin uint32_t aqa; /* admin queue attributes */
755bb0ec6b3SJim Harris uint64_t asq; /* admin submission queue base addr */
756bb0ec6b3SJim Harris uint64_t acq; /* admin completion queue base addr */
757a6d222ebSAlexander Motin uint32_t cmbloc; /* Controller Memory Buffer Location */
758a6d222ebSAlexander Motin uint32_t cmbsz; /* Controller Memory Buffer Size */
759a6d222ebSAlexander Motin uint32_t bpinfo; /* Boot Partition Information */
760a6d222ebSAlexander Motin uint32_t bprsel; /* Boot Partition Read Select */
761a6d222ebSAlexander Motin uint64_t bpmbl; /* Boot Partition Memory Buffer Location */
762a6d222ebSAlexander Motin uint64_t cmbmsc; /* Controller Memory Buffer Memory Space Control */
763a6d222ebSAlexander Motin uint32_t cmbsts; /* Controller Memory Buffer Status */
764b46c7b1eSAlexander Motin uint32_t cmbebs; /* Controller Memory Buffer Elasticity Buffer Size */
765b46c7b1eSAlexander Motin uint32_t cmbswtp;/* Controller Memory Buffer Sustained Write Throughput */
766b46c7b1eSAlexander Motin uint32_t nssd; /* NVM Subsystem Shutdown */
767b46c7b1eSAlexander Motin uint32_t crto; /* Controller Ready Timeouts */
768b46c7b1eSAlexander Motin uint8_t reserved3[3476]; /* 6Ch - DFFh */
769a6d222ebSAlexander Motin uint32_t pmrcap; /* Persistent Memory Capabilities */
770a6d222ebSAlexander Motin uint32_t pmrctl; /* Persistent Memory Region Control */
771a6d222ebSAlexander Motin uint32_t pmrsts; /* Persistent Memory Region Status */
772a6d222ebSAlexander Motin uint32_t pmrebs; /* Persistent Memory Region Elasticity Buffer Size */
773a6d222ebSAlexander Motin uint32_t pmrswtp; /* Persistent Memory Region Sustained Write Throughput */
774a6d222ebSAlexander Motin uint32_t pmrmsc_lo; /* Persistent Memory Region Controller Memory Space Control */
775a6d222ebSAlexander Motin uint32_t pmrmsc_hi;
776a6d222ebSAlexander Motin uint8_t reserved4[484]; /* E1Ch - FFFh */
777bb0ec6b3SJim Harris struct {
778bb0ec6b3SJim Harris uint32_t sq_tdbl; /* submission queue tail doorbell */
779bb0ec6b3SJim Harris uint32_t cq_hdbl; /* completion queue head doorbell */
780fea3cf1dSWarner Losh } doorbell[1];
781fea3cf1dSWarner Losh };
782bb0ec6b3SJim Harris
7830012e436SWarner Losh _Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers");
7840c26c199SWarner Losh
785f21a54d1SJohn Baldwin #define NVME_SGL_SUBTYPE_SHIFT (0)
786f21a54d1SJohn Baldwin #define NVME_SGL_SUBTYPE_MASK (0xF)
787f21a54d1SJohn Baldwin #define NVME_SGL_TYPE_SHIFT (4)
788f21a54d1SJohn Baldwin #define NVME_SGL_TYPE_MASK (0xF)
789f21a54d1SJohn Baldwin
790f21a54d1SJohn Baldwin #define NVME_SGL_TYPE(type, subtype) \
791f21a54d1SJohn Baldwin ((subtype) << NVME_SGL_SUBTYPE_SHIFT | (type) << NVME_SGL_TYPE_SHIFT)
792f21a54d1SJohn Baldwin
793f21a54d1SJohn Baldwin enum nvme_sgl_type {
794f21a54d1SJohn Baldwin NVME_SGL_TYPE_DATA_BLOCK = 0x0,
795f21a54d1SJohn Baldwin NVME_SGL_TYPE_BIT_BUCKET = 0x1,
796f21a54d1SJohn Baldwin NVME_SGL_TYPE_SEGMENT = 0x2,
797f21a54d1SJohn Baldwin NVME_SGL_TYPE_LAST_SEGMENT = 0x3,
798f21a54d1SJohn Baldwin NVME_SGL_TYPE_KEYED_DATA_BLOCK = 0x4,
799f21a54d1SJohn Baldwin NVME_SGL_TYPE_TRANSPORT_DATA_BLOCK = 0x5,
800f21a54d1SJohn Baldwin };
801f21a54d1SJohn Baldwin
802f21a54d1SJohn Baldwin enum nvme_sgl_subtype {
803f21a54d1SJohn Baldwin NVME_SGL_SUBTYPE_ADDRESS = 0x0,
804f21a54d1SJohn Baldwin NVME_SGL_SUBTYPE_OFFSET = 0x1,
805f21a54d1SJohn Baldwin NVME_SGL_SUBTYPE_TRANSPORT = 0xa,
806f21a54d1SJohn Baldwin };
807f21a54d1SJohn Baldwin
808f21a54d1SJohn Baldwin struct nvme_sgl_descriptor {
809f21a54d1SJohn Baldwin uint64_t address;
810f21a54d1SJohn Baldwin uint32_t length;
811f21a54d1SJohn Baldwin uint8_t reserved[3];
812f21a54d1SJohn Baldwin uint8_t type;
813f21a54d1SJohn Baldwin };
814f21a54d1SJohn Baldwin
815f21a54d1SJohn Baldwin _Static_assert(sizeof(struct nvme_sgl_descriptor) == 16, "bad size for nvme_sgl_descriptor");
816f21a54d1SJohn Baldwin
81780a75155SWarner Losh struct nvme_command {
818bb0ec6b3SJim Harris /* dword 0 */
8199544e6dcSChuck Tuffli uint8_t opc; /* opcode */
8209544e6dcSChuck Tuffli uint8_t fuse; /* fused operation */
821bb0ec6b3SJim Harris uint16_t cid; /* command identifier */
822bb0ec6b3SJim Harris
823bb0ec6b3SJim Harris /* dword 1 */
824bb0ec6b3SJim Harris uint32_t nsid; /* namespace identifier */
825bb0ec6b3SJim Harris
826bb0ec6b3SJim Harris /* dword 2-3 */
827bb0ec6b3SJim Harris uint32_t rsvd2;
828bb0ec6b3SJim Harris uint32_t rsvd3;
829bb0ec6b3SJim Harris
830bb0ec6b3SJim Harris /* dword 4-5 */
831bb0ec6b3SJim Harris uint64_t mptr; /* metadata pointer */
832bb0ec6b3SJim Harris
833f21a54d1SJohn Baldwin /* dword 6-9 */
834f21a54d1SJohn Baldwin union {
835f21a54d1SJohn Baldwin struct {
836bb0ec6b3SJim Harris uint64_t prp1; /* prp entry 1 */
837bb0ec6b3SJim Harris uint64_t prp2; /* prp entry 2 */
838f21a54d1SJohn Baldwin };
839f21a54d1SJohn Baldwin struct nvme_sgl_descriptor sgl;
840f21a54d1SJohn Baldwin };
841bb0ec6b3SJim Harris
842bb0ec6b3SJim Harris /* dword 10-15 */
843bb0ec6b3SJim Harris uint32_t cdw10; /* command-specific */
844bb0ec6b3SJim Harris uint32_t cdw11; /* command-specific */
845bb0ec6b3SJim Harris uint32_t cdw12; /* command-specific */
846bb0ec6b3SJim Harris uint32_t cdw13; /* command-specific */
847bb0ec6b3SJim Harris uint32_t cdw14; /* command-specific */
848bb0ec6b3SJim Harris uint32_t cdw15; /* command-specific */
849ebcfab99SJohn Baldwin } __aligned(8);
850bb0ec6b3SJim Harris
8510012e436SWarner Losh _Static_assert(sizeof(struct nvme_command) == 16 * 4, "bad size for nvme_command");
8520c26c199SWarner Losh
853bb0ec6b3SJim Harris struct nvme_completion {
854bb0ec6b3SJim Harris /* dword 0 */
855bb0ec6b3SJim Harris uint32_t cdw0; /* command-specific */
856bb0ec6b3SJim Harris
857bb0ec6b3SJim Harris /* dword 1 */
858bb0ec6b3SJim Harris uint32_t rsvd1;
859bb0ec6b3SJim Harris
860bb0ec6b3SJim Harris /* dword 2 */
861bb0ec6b3SJim Harris uint16_t sqhd; /* submission queue head pointer */
862bb0ec6b3SJim Harris uint16_t sqid; /* submission queue identifier */
863bb0ec6b3SJim Harris
864bb0ec6b3SJim Harris /* dword 3 */
865bb0ec6b3SJim Harris uint16_t cid; /* command identifier */
8660d787e9bSWojciech Macek uint16_t status;
867fea3cf1dSWarner Losh } __aligned(8); /* riscv: nvme_qpair_process_completions has better code gen */
868bb0ec6b3SJim Harris
8690012e436SWarner Losh _Static_assert(sizeof(struct nvme_completion) == 4 * 4, "bad size for nvme_completion");
8700c26c199SWarner Losh
871bb0ec6b3SJim Harris struct nvme_dsm_range {
872bb0ec6b3SJim Harris uint32_t attributes;
873bb0ec6b3SJim Harris uint32_t length;
874bb0ec6b3SJim Harris uint64_t starting_lba;
875fea3cf1dSWarner Losh };
876bb0ec6b3SJim Harris
877807e94b2SWarner Losh /* Largest DSM Trim that can be done */
878807e94b2SWarner Losh #define NVME_MAX_DSM_TRIM 4096
879807e94b2SWarner Losh
8800012e436SWarner Losh _Static_assert(sizeof(struct nvme_dsm_range) == 16, "bad size for nvme_dsm_ranage");
8810c26c199SWarner Losh
882bb0ec6b3SJim Harris /* status code types */
883bb0ec6b3SJim Harris enum nvme_status_code_type {
884bb0ec6b3SJim Harris NVME_SCT_GENERIC = 0x0,
885bb0ec6b3SJim Harris NVME_SCT_COMMAND_SPECIFIC = 0x1,
886bb0ec6b3SJim Harris NVME_SCT_MEDIA_ERROR = 0x2,
887a6d222ebSAlexander Motin NVME_SCT_PATH_RELATED = 0x3,
888bb0ec6b3SJim Harris /* 0x3-0x6 - reserved */
889bb0ec6b3SJim Harris NVME_SCT_VENDOR_SPECIFIC = 0x7,
890bb0ec6b3SJim Harris };
891bb0ec6b3SJim Harris
892bb0ec6b3SJim Harris /* generic command status codes */
893bb0ec6b3SJim Harris enum nvme_generic_command_status_code {
894bb0ec6b3SJim Harris NVME_SC_SUCCESS = 0x00,
895bb0ec6b3SJim Harris NVME_SC_INVALID_OPCODE = 0x01,
896bb0ec6b3SJim Harris NVME_SC_INVALID_FIELD = 0x02,
897bb0ec6b3SJim Harris NVME_SC_COMMAND_ID_CONFLICT = 0x03,
898bb0ec6b3SJim Harris NVME_SC_DATA_TRANSFER_ERROR = 0x04,
899bb0ec6b3SJim Harris NVME_SC_ABORTED_POWER_LOSS = 0x05,
900bb0ec6b3SJim Harris NVME_SC_INTERNAL_DEVICE_ERROR = 0x06,
901bb0ec6b3SJim Harris NVME_SC_ABORTED_BY_REQUEST = 0x07,
902bb0ec6b3SJim Harris NVME_SC_ABORTED_SQ_DELETION = 0x08,
903bb0ec6b3SJim Harris NVME_SC_ABORTED_FAILED_FUSED = 0x09,
904bb0ec6b3SJim Harris NVME_SC_ABORTED_MISSING_FUSED = 0x0a,
905bb0ec6b3SJim Harris NVME_SC_INVALID_NAMESPACE_OR_FORMAT = 0x0b,
906bb0ec6b3SJim Harris NVME_SC_COMMAND_SEQUENCE_ERROR = 0x0c,
9076b1a96b1SAlexander Motin NVME_SC_INVALID_SGL_SEGMENT_DESCR = 0x0d,
9086b1a96b1SAlexander Motin NVME_SC_INVALID_NUMBER_OF_SGL_DESCR = 0x0e,
9096b1a96b1SAlexander Motin NVME_SC_DATA_SGL_LENGTH_INVALID = 0x0f,
9106b1a96b1SAlexander Motin NVME_SC_METADATA_SGL_LENGTH_INVALID = 0x10,
9116b1a96b1SAlexander Motin NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID = 0x11,
9126b1a96b1SAlexander Motin NVME_SC_INVALID_USE_OF_CMB = 0x12,
9136b1a96b1SAlexander Motin NVME_SC_PRP_OFFET_INVALID = 0x13,
9146b1a96b1SAlexander Motin NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED = 0x14,
9156b1a96b1SAlexander Motin NVME_SC_OPERATION_DENIED = 0x15,
9166b1a96b1SAlexander Motin NVME_SC_SGL_OFFSET_INVALID = 0x16,
9176b1a96b1SAlexander Motin /* 0x17 - reserved */
9186b1a96b1SAlexander Motin NVME_SC_HOST_ID_INCONSISTENT_FORMAT = 0x18,
9196b1a96b1SAlexander Motin NVME_SC_KEEP_ALIVE_TIMEOUT_EXPIRED = 0x19,
9206b1a96b1SAlexander Motin NVME_SC_KEEP_ALIVE_TIMEOUT_INVALID = 0x1a,
9216b1a96b1SAlexander Motin NVME_SC_ABORTED_DUE_TO_PREEMPT = 0x1b,
9226b1a96b1SAlexander Motin NVME_SC_SANITIZE_FAILED = 0x1c,
9236b1a96b1SAlexander Motin NVME_SC_SANITIZE_IN_PROGRESS = 0x1d,
9246b1a96b1SAlexander Motin NVME_SC_SGL_DATA_BLOCK_GRAN_INVALID = 0x1e,
9256b1a96b1SAlexander Motin NVME_SC_NOT_SUPPORTED_IN_CMB = 0x1f,
92690dfa8f0SAlexander Motin NVME_SC_NAMESPACE_IS_WRITE_PROTECTED = 0x20,
92790dfa8f0SAlexander Motin NVME_SC_COMMAND_INTERRUPTED = 0x21,
92890dfa8f0SAlexander Motin NVME_SC_TRANSIENT_TRANSPORT_ERROR = 0x22,
929bb0ec6b3SJim Harris
930bb0ec6b3SJim Harris NVME_SC_LBA_OUT_OF_RANGE = 0x80,
931bb0ec6b3SJim Harris NVME_SC_CAPACITY_EXCEEDED = 0x81,
932bb0ec6b3SJim Harris NVME_SC_NAMESPACE_NOT_READY = 0x82,
9336b1a96b1SAlexander Motin NVME_SC_RESERVATION_CONFLICT = 0x83,
9346b1a96b1SAlexander Motin NVME_SC_FORMAT_IN_PROGRESS = 0x84,
935bb0ec6b3SJim Harris };
936bb0ec6b3SJim Harris
937bb0ec6b3SJim Harris /* command specific status codes */
938bb0ec6b3SJim Harris enum nvme_command_specific_status_code {
939bb0ec6b3SJim Harris NVME_SC_COMPLETION_QUEUE_INVALID = 0x00,
940bb0ec6b3SJim Harris NVME_SC_INVALID_QUEUE_IDENTIFIER = 0x01,
941bb0ec6b3SJim Harris NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED = 0x02,
942bb0ec6b3SJim Harris NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED = 0x03,
943bb0ec6b3SJim Harris /* 0x04 - reserved */
944bb0ec6b3SJim Harris NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
945bb0ec6b3SJim Harris NVME_SC_INVALID_FIRMWARE_SLOT = 0x06,
946bb0ec6b3SJim Harris NVME_SC_INVALID_FIRMWARE_IMAGE = 0x07,
947bb0ec6b3SJim Harris NVME_SC_INVALID_INTERRUPT_VECTOR = 0x08,
948bb0ec6b3SJim Harris NVME_SC_INVALID_LOG_PAGE = 0x09,
949bb0ec6b3SJim Harris NVME_SC_INVALID_FORMAT = 0x0a,
950bb0ec6b3SJim Harris NVME_SC_FIRMWARE_REQUIRES_RESET = 0x0b,
9516b1a96b1SAlexander Motin NVME_SC_INVALID_QUEUE_DELETION = 0x0c,
9526b1a96b1SAlexander Motin NVME_SC_FEATURE_NOT_SAVEABLE = 0x0d,
9536b1a96b1SAlexander Motin NVME_SC_FEATURE_NOT_CHANGEABLE = 0x0e,
9546b1a96b1SAlexander Motin NVME_SC_FEATURE_NOT_NS_SPECIFIC = 0x0f,
9556b1a96b1SAlexander Motin NVME_SC_FW_ACT_REQUIRES_NVMS_RESET = 0x10,
9566b1a96b1SAlexander Motin NVME_SC_FW_ACT_REQUIRES_RESET = 0x11,
9576b1a96b1SAlexander Motin NVME_SC_FW_ACT_REQUIRES_TIME = 0x12,
9586b1a96b1SAlexander Motin NVME_SC_FW_ACT_PROHIBITED = 0x13,
9596b1a96b1SAlexander Motin NVME_SC_OVERLAPPING_RANGE = 0x14,
9606b1a96b1SAlexander Motin NVME_SC_NS_INSUFFICIENT_CAPACITY = 0x15,
9616b1a96b1SAlexander Motin NVME_SC_NS_ID_UNAVAILABLE = 0x16,
9626b1a96b1SAlexander Motin /* 0x17 - reserved */
9636b1a96b1SAlexander Motin NVME_SC_NS_ALREADY_ATTACHED = 0x18,
9646b1a96b1SAlexander Motin NVME_SC_NS_IS_PRIVATE = 0x19,
9656b1a96b1SAlexander Motin NVME_SC_NS_NOT_ATTACHED = 0x1a,
9666b1a96b1SAlexander Motin NVME_SC_THIN_PROV_NOT_SUPPORTED = 0x1b,
9676b1a96b1SAlexander Motin NVME_SC_CTRLR_LIST_INVALID = 0x1c,
9688d08cdc7SChuck Tuffli NVME_SC_SELF_TEST_IN_PROGRESS = 0x1d,
9696b1a96b1SAlexander Motin NVME_SC_BOOT_PART_WRITE_PROHIB = 0x1e,
9706b1a96b1SAlexander Motin NVME_SC_INVALID_CTRLR_ID = 0x1f,
9716b1a96b1SAlexander Motin NVME_SC_INVALID_SEC_CTRLR_STATE = 0x20,
9726b1a96b1SAlexander Motin NVME_SC_INVALID_NUM_OF_CTRLR_RESRC = 0x21,
9736b1a96b1SAlexander Motin NVME_SC_INVALID_RESOURCE_ID = 0x22,
97490dfa8f0SAlexander Motin NVME_SC_SANITIZE_PROHIBITED_WPMRE = 0x23,
97590dfa8f0SAlexander Motin NVME_SC_ANA_GROUP_ID_INVALID = 0x24,
97690dfa8f0SAlexander Motin NVME_SC_ANA_ATTACH_FAILED = 0x25,
977bb0ec6b3SJim Harris
978bb0ec6b3SJim Harris NVME_SC_CONFLICTING_ATTRIBUTES = 0x80,
979bb0ec6b3SJim Harris NVME_SC_INVALID_PROTECTION_INFO = 0x81,
980bb0ec6b3SJim Harris NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE = 0x82,
981bb0ec6b3SJim Harris };
982bb0ec6b3SJim Harris
983bb0ec6b3SJim Harris /* media error status codes */
984bb0ec6b3SJim Harris enum nvme_media_error_status_code {
985bb0ec6b3SJim Harris NVME_SC_WRITE_FAULTS = 0x80,
986bb0ec6b3SJim Harris NVME_SC_UNRECOVERED_READ_ERROR = 0x81,
987bb0ec6b3SJim Harris NVME_SC_GUARD_CHECK_ERROR = 0x82,
988bb0ec6b3SJim Harris NVME_SC_APPLICATION_TAG_CHECK_ERROR = 0x83,
989bb0ec6b3SJim Harris NVME_SC_REFERENCE_TAG_CHECK_ERROR = 0x84,
990bb0ec6b3SJim Harris NVME_SC_COMPARE_FAILURE = 0x85,
991bb0ec6b3SJim Harris NVME_SC_ACCESS_DENIED = 0x86,
9926b1a96b1SAlexander Motin NVME_SC_DEALLOCATED_OR_UNWRITTEN = 0x87,
993bb0ec6b3SJim Harris };
994bb0ec6b3SJim Harris
995a6d222ebSAlexander Motin /* path related status codes */
996a6d222ebSAlexander Motin enum nvme_path_related_status_code {
997a6d222ebSAlexander Motin NVME_SC_INTERNAL_PATH_ERROR = 0x00,
998a6d222ebSAlexander Motin NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS = 0x01,
999a6d222ebSAlexander Motin NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE = 0x02,
1000a6d222ebSAlexander Motin NVME_SC_ASYMMETRIC_ACCESS_TRANSITION = 0x03,
1001a6d222ebSAlexander Motin NVME_SC_CONTROLLER_PATHING_ERROR = 0x60,
1002a6d222ebSAlexander Motin NVME_SC_HOST_PATHING_ERROR = 0x70,
10035ae44634SJohn Baldwin NVME_SC_COMMAND_ABORTED_BY_HOST = 0x71,
1004a6d222ebSAlexander Motin };
1005a6d222ebSAlexander Motin
1006bb0ec6b3SJim Harris /* admin opcodes */
1007bb0ec6b3SJim Harris enum nvme_admin_opcode {
1008bb0ec6b3SJim Harris NVME_OPC_DELETE_IO_SQ = 0x00,
1009bb0ec6b3SJim Harris NVME_OPC_CREATE_IO_SQ = 0x01,
1010bb0ec6b3SJim Harris NVME_OPC_GET_LOG_PAGE = 0x02,
1011bb0ec6b3SJim Harris /* 0x03 - reserved */
1012bb0ec6b3SJim Harris NVME_OPC_DELETE_IO_CQ = 0x04,
1013bb0ec6b3SJim Harris NVME_OPC_CREATE_IO_CQ = 0x05,
1014bb0ec6b3SJim Harris NVME_OPC_IDENTIFY = 0x06,
1015bb0ec6b3SJim Harris /* 0x07 - reserved */
1016bb0ec6b3SJim Harris NVME_OPC_ABORT = 0x08,
1017bb0ec6b3SJim Harris NVME_OPC_SET_FEATURES = 0x09,
1018bb0ec6b3SJim Harris NVME_OPC_GET_FEATURES = 0x0a,
1019bb0ec6b3SJim Harris /* 0x0b - reserved */
1020bb0ec6b3SJim Harris NVME_OPC_ASYNC_EVENT_REQUEST = 0x0c,
1021594ffc03SWarner Losh NVME_OPC_NAMESPACE_MANAGEMENT = 0x0d,
1022594ffc03SWarner Losh /* 0x0e-0x0f - reserved */
1023bb0ec6b3SJim Harris NVME_OPC_FIRMWARE_ACTIVATE = 0x10,
1024bb0ec6b3SJim Harris NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD = 0x11,
102590dfa8f0SAlexander Motin /* 0x12-0x13 - reserved */
10266b1a96b1SAlexander Motin NVME_OPC_DEVICE_SELF_TEST = 0x14,
1027594ffc03SWarner Losh NVME_OPC_NAMESPACE_ATTACHMENT = 0x15,
102890dfa8f0SAlexander Motin /* 0x16-0x17 - reserved */
10296b1a96b1SAlexander Motin NVME_OPC_KEEP_ALIVE = 0x18,
10306b1a96b1SAlexander Motin NVME_OPC_DIRECTIVE_SEND = 0x19,
10316b1a96b1SAlexander Motin NVME_OPC_DIRECTIVE_RECEIVE = 0x1a,
103290dfa8f0SAlexander Motin /* 0x1b - reserved */
10336b1a96b1SAlexander Motin NVME_OPC_VIRTUALIZATION_MANAGEMENT = 0x1c,
10346b1a96b1SAlexander Motin NVME_OPC_NVME_MI_SEND = 0x1d,
10356b1a96b1SAlexander Motin NVME_OPC_NVME_MI_RECEIVE = 0x1e,
1036ac8c866fSWarner Losh /* 0x1f - reserved */
1037ac8c866fSWarner Losh NVME_OPC_CAPACITY_MANAGEMENT = 0x20,
1038ac8c866fSWarner Losh /* 0x21-0x23 - reserved */
1039ac8c866fSWarner Losh NVME_OPC_LOCKDOWN = 0x24,
1040081c22dbSJohn Baldwin /* 0x25-0x7b - reserved */
10416b1a96b1SAlexander Motin NVME_OPC_DOORBELL_BUFFER_CONFIG = 0x7c,
1042ac8c866fSWarner Losh /* 0x7d-0x7e - reserved */
1043ac8c866fSWarner Losh NVME_OPC_FABRICS_COMMANDS = 0x7f,
1044bb0ec6b3SJim Harris
1045bb0ec6b3SJim Harris NVME_OPC_FORMAT_NVM = 0x80,
1046bb0ec6b3SJim Harris NVME_OPC_SECURITY_SEND = 0x81,
1047bb0ec6b3SJim Harris NVME_OPC_SECURITY_RECEIVE = 0x82,
104890dfa8f0SAlexander Motin /* 0x83 - reserved */
10496b1a96b1SAlexander Motin NVME_OPC_SANITIZE = 0x84,
105090dfa8f0SAlexander Motin /* 0x85 - reserved */
105190dfa8f0SAlexander Motin NVME_OPC_GET_LBA_STATUS = 0x86,
1052bb0ec6b3SJim Harris };
1053bb0ec6b3SJim Harris
1054bb0ec6b3SJim Harris /* nvme nvm opcodes */
1055bb0ec6b3SJim Harris enum nvme_nvm_opcode {
1056bb0ec6b3SJim Harris NVME_OPC_FLUSH = 0x00,
1057bb0ec6b3SJim Harris NVME_OPC_WRITE = 0x01,
1058bb0ec6b3SJim Harris NVME_OPC_READ = 0x02,
1059bb0ec6b3SJim Harris /* 0x03 - reserved */
1060bb0ec6b3SJim Harris NVME_OPC_WRITE_UNCORRECTABLE = 0x04,
1061bb0ec6b3SJim Harris NVME_OPC_COMPARE = 0x05,
106290dfa8f0SAlexander Motin /* 0x06-0x07 - reserved */
10636b1a96b1SAlexander Motin NVME_OPC_WRITE_ZEROES = 0x08,
1064bb0ec6b3SJim Harris NVME_OPC_DATASET_MANAGEMENT = 0x09,
106590dfa8f0SAlexander Motin /* 0x0a-0x0b - reserved */
106690dfa8f0SAlexander Motin NVME_OPC_VERIFY = 0x0c,
10676b1a96b1SAlexander Motin NVME_OPC_RESERVATION_REGISTER = 0x0d,
10686b1a96b1SAlexander Motin NVME_OPC_RESERVATION_REPORT = 0x0e,
10696b1a96b1SAlexander Motin /* 0x0f-0x10 - reserved */
10706b1a96b1SAlexander Motin NVME_OPC_RESERVATION_ACQUIRE = 0x11,
10716b1a96b1SAlexander Motin /* 0x12-0x14 - reserved */
10726b1a96b1SAlexander Motin NVME_OPC_RESERVATION_RELEASE = 0x15,
1073ac8c866fSWarner Losh /* 0x16-0x18 - reserved */
1074ac8c866fSWarner Losh NVME_OPC_COPY = 0x19,
1075bb0ec6b3SJim Harris };
1076bb0ec6b3SJim Harris
1077bb0ec6b3SJim Harris enum nvme_feature {
1078bb0ec6b3SJim Harris /* 0x00 - reserved */
1079bb0ec6b3SJim Harris NVME_FEAT_ARBITRATION = 0x01,
1080bb0ec6b3SJim Harris NVME_FEAT_POWER_MANAGEMENT = 0x02,
1081bb0ec6b3SJim Harris NVME_FEAT_LBA_RANGE_TYPE = 0x03,
1082bb0ec6b3SJim Harris NVME_FEAT_TEMPERATURE_THRESHOLD = 0x04,
1083bb0ec6b3SJim Harris NVME_FEAT_ERROR_RECOVERY = 0x05,
1084bb0ec6b3SJim Harris NVME_FEAT_VOLATILE_WRITE_CACHE = 0x06,
1085bb0ec6b3SJim Harris NVME_FEAT_NUMBER_OF_QUEUES = 0x07,
1086bb0ec6b3SJim Harris NVME_FEAT_INTERRUPT_COALESCING = 0x08,
1087bb0ec6b3SJim Harris NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
1088bb0ec6b3SJim Harris NVME_FEAT_WRITE_ATOMICITY = 0x0A,
10890a0b08ccSJim Harris NVME_FEAT_ASYNC_EVENT_CONFIGURATION = 0x0B,
1090223a9b93SWarner Losh NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
1091223a9b93SWarner Losh NVME_FEAT_HOST_MEMORY_BUFFER = 0x0D,
1092223a9b93SWarner Losh NVME_FEAT_TIMESTAMP = 0x0E,
1093223a9b93SWarner Losh NVME_FEAT_KEEP_ALIVE_TIMER = 0x0F,
1094223a9b93SWarner Losh NVME_FEAT_HOST_CONTROLLED_THERMAL_MGMT = 0x10,
1095223a9b93SWarner Losh NVME_FEAT_NON_OP_POWER_STATE_CONFIG = 0x11,
109690dfa8f0SAlexander Motin NVME_FEAT_READ_RECOVERY_LEVEL_CONFIG = 0x12,
109790dfa8f0SAlexander Motin NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG = 0x13,
109890dfa8f0SAlexander Motin NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW = 0x14,
109990dfa8f0SAlexander Motin NVME_FEAT_LBA_STATUS_INFORMATION_ATTRIBUTES = 0x15,
110090dfa8f0SAlexander Motin NVME_FEAT_HOST_BEHAVIOR_SUPPORT = 0x16,
110190dfa8f0SAlexander Motin NVME_FEAT_SANITIZE_CONFIG = 0x17,
110290dfa8f0SAlexander Motin NVME_FEAT_ENDURANCE_GROUP_EVENT_CONFIGURATION = 0x18,
110390dfa8f0SAlexander Motin /* 0x19-0x77 - reserved */
1104223a9b93SWarner Losh /* 0x78-0x7f - NVMe Management Interface */
1105bb0ec6b3SJim Harris NVME_FEAT_SOFTWARE_PROGRESS_MARKER = 0x80,
110690dfa8f0SAlexander Motin NVME_FEAT_HOST_IDENTIFIER = 0x81,
110790dfa8f0SAlexander Motin NVME_FEAT_RESERVATION_NOTIFICATION_MASK = 0x82,
110890dfa8f0SAlexander Motin NVME_FEAT_RESERVATION_PERSISTENCE = 0x83,
110990dfa8f0SAlexander Motin NVME_FEAT_NAMESPACE_WRITE_PROTECTION_CONFIG = 0x84,
111090dfa8f0SAlexander Motin /* 0x85-0xBF - command set specific (reserved) */
1111bb0ec6b3SJim Harris /* 0xC0-0xFF - vendor specific */
1112bb0ec6b3SJim Harris };
1113bb0ec6b3SJim Harris
1114bb0ec6b3SJim Harris enum nvme_dsm_attribute {
1115bb0ec6b3SJim Harris NVME_DSM_ATTR_INTEGRAL_READ = 0x1,
1116bb0ec6b3SJim Harris NVME_DSM_ATTR_INTEGRAL_WRITE = 0x2,
1117bb0ec6b3SJim Harris NVME_DSM_ATTR_DEALLOCATE = 0x4,
1118bb0ec6b3SJim Harris };
1119bb0ec6b3SJim Harris
112049fac610SJim Harris enum nvme_activate_action {
112149fac610SJim Harris NVME_AA_REPLACE_NO_ACTIVATE = 0x0,
112249fac610SJim Harris NVME_AA_REPLACE_ACTIVATE = 0x1,
112349fac610SJim Harris NVME_AA_ACTIVATE = 0x2,
112449fac610SJim Harris };
112549fac610SJim Harris
1126038659e7SWarner Losh struct nvme_power_state {
1127038659e7SWarner Losh /** Maximum Power */
1128038659e7SWarner Losh uint16_t mp; /* Maximum Power */
1129038659e7SWarner Losh uint8_t ps_rsvd1;
11300d787e9bSWojciech Macek uint8_t mps_nops; /* Max Power Scale, Non-Operational State */
11310d787e9bSWojciech Macek
1132038659e7SWarner Losh uint32_t enlat; /* Entry Latency */
1133038659e7SWarner Losh uint32_t exlat; /* Exit Latency */
11340d787e9bSWojciech Macek
11350d787e9bSWojciech Macek uint8_t rrt; /* Relative Read Throughput */
11360d787e9bSWojciech Macek uint8_t rrl; /* Relative Read Latency */
11370d787e9bSWojciech Macek uint8_t rwt; /* Relative Write Throughput */
11380d787e9bSWojciech Macek uint8_t rwl; /* Relative Write Latency */
11390d787e9bSWojciech Macek
1140038659e7SWarner Losh uint16_t idlp; /* Idle Power */
11410d787e9bSWojciech Macek uint8_t ips; /* Idle Power Scale */
1142038659e7SWarner Losh uint8_t ps_rsvd8;
11430d787e9bSWojciech Macek
1144038659e7SWarner Losh uint16_t actp; /* Active Power */
11450d787e9bSWojciech Macek uint8_t apw_aps; /* Active Power Workload, Active Power Scale */
1146038659e7SWarner Losh uint8_t ps_rsvd10[9];
1147038659e7SWarner Losh } __packed;
1148038659e7SWarner Losh
11490012e436SWarner Losh _Static_assert(sizeof(struct nvme_power_state) == 32, "bad size for nvme_power_state");
11500c26c199SWarner Losh
1151e8f25c62SJim Harris #define NVME_SERIAL_NUMBER_LENGTH 20
1152e8f25c62SJim Harris #define NVME_MODEL_NUMBER_LENGTH 40
1153e8f25c62SJim Harris #define NVME_FIRMWARE_REVISION_LENGTH 8
1154e8f25c62SJim Harris
1155bb0ec6b3SJim Harris struct nvme_controller_data {
1156bb0ec6b3SJim Harris /* bytes 0-255: controller capabilities and features */
1157bb0ec6b3SJim Harris
1158bb0ec6b3SJim Harris /** pci vendor id */
1159bb0ec6b3SJim Harris uint16_t vid;
1160bb0ec6b3SJim Harris
1161bb0ec6b3SJim Harris /** pci subsystem vendor id */
1162bb0ec6b3SJim Harris uint16_t ssvid;
1163bb0ec6b3SJim Harris
1164bb0ec6b3SJim Harris /** serial number */
116538441bd9SJim Harris uint8_t sn[NVME_SERIAL_NUMBER_LENGTH];
1166bb0ec6b3SJim Harris
1167bb0ec6b3SJim Harris /** model number */
116838441bd9SJim Harris uint8_t mn[NVME_MODEL_NUMBER_LENGTH];
1169bb0ec6b3SJim Harris
1170bb0ec6b3SJim Harris /** firmware revision */
1171e8f25c62SJim Harris uint8_t fr[NVME_FIRMWARE_REVISION_LENGTH];
1172bb0ec6b3SJim Harris
1173bb0ec6b3SJim Harris /** recommended arbitration burst */
1174bb0ec6b3SJim Harris uint8_t rab;
1175bb0ec6b3SJim Harris
1176bb0ec6b3SJim Harris /** ieee oui identifier */
1177bb0ec6b3SJim Harris uint8_t ieee[3];
1178bb0ec6b3SJim Harris
1179bb0ec6b3SJim Harris /** multi-interface capabilities */
1180bb0ec6b3SJim Harris uint8_t mic;
1181bb0ec6b3SJim Harris
1182bb0ec6b3SJim Harris /** maximum data transfer size */
1183bb0ec6b3SJim Harris uint8_t mdts;
1184bb0ec6b3SJim Harris
1185594ffc03SWarner Losh /** Controller ID */
1186594ffc03SWarner Losh uint16_t ctrlr_id;
1187594ffc03SWarner Losh
1188030edcceSWarner Losh /** Version */
1189030edcceSWarner Losh uint32_t ver;
1190030edcceSWarner Losh
1191030edcceSWarner Losh /** RTD3 Resume Latency */
1192030edcceSWarner Losh uint32_t rtd3r;
1193030edcceSWarner Losh
1194030edcceSWarner Losh /** RTD3 Enter Latency */
1195030edcceSWarner Losh uint32_t rtd3e;
1196030edcceSWarner Losh
1197030edcceSWarner Losh /** Optional Asynchronous Events Supported */
1198030edcceSWarner Losh uint32_t oaes; /* bitfield really */
1199030edcceSWarner Losh
1200030edcceSWarner Losh /** Controller Attributes */
1201030edcceSWarner Losh uint32_t ctratt; /* bitfield really */
1202030edcceSWarner Losh
12038de2d8c0SAlexander Motin /** Read Recovery Levels Supported */
12048de2d8c0SAlexander Motin uint16_t rrls;
12058de2d8c0SAlexander Motin
12068de2d8c0SAlexander Motin uint8_t reserved1[9];
12078de2d8c0SAlexander Motin
12088de2d8c0SAlexander Motin /** Controller Type */
12098de2d8c0SAlexander Motin uint8_t cntrltype;
1210030edcceSWarner Losh
1211030edcceSWarner Losh /** FRU Globally Unique Identifier */
1212030edcceSWarner Losh uint8_t fguid[16];
1213030edcceSWarner Losh
12148de2d8c0SAlexander Motin /** Command Retry Delay Time 1 */
12158de2d8c0SAlexander Motin uint16_t crdt1;
12168de2d8c0SAlexander Motin
12178de2d8c0SAlexander Motin /** Command Retry Delay Time 2 */
12188de2d8c0SAlexander Motin uint16_t crdt2;
12198de2d8c0SAlexander Motin
12208de2d8c0SAlexander Motin /** Command Retry Delay Time 3 */
12218de2d8c0SAlexander Motin uint16_t crdt3;
12228de2d8c0SAlexander Motin
12238de2d8c0SAlexander Motin uint8_t reserved2[122];
1224bb0ec6b3SJim Harris
1225bb0ec6b3SJim Harris /* bytes 256-511: admin command set attributes */
1226bb0ec6b3SJim Harris
1227bb0ec6b3SJim Harris /** optional admin command support */
12280d787e9bSWojciech Macek uint16_t oacs;
1229bb0ec6b3SJim Harris
1230bb0ec6b3SJim Harris /** abort command limit */
1231bb0ec6b3SJim Harris uint8_t acl;
1232bb0ec6b3SJim Harris
1233bb0ec6b3SJim Harris /** asynchronous event request limit */
1234bb0ec6b3SJim Harris uint8_t aerl;
1235bb0ec6b3SJim Harris
1236bb0ec6b3SJim Harris /** firmware updates */
12370d787e9bSWojciech Macek uint8_t frmw;
1238bb0ec6b3SJim Harris
1239bb0ec6b3SJim Harris /** log page attributes */
12400d787e9bSWojciech Macek uint8_t lpa;
1241bb0ec6b3SJim Harris
1242bb0ec6b3SJim Harris /** error log page entries */
1243bb0ec6b3SJim Harris uint8_t elpe;
1244bb0ec6b3SJim Harris
1245bb0ec6b3SJim Harris /** number of power states supported */
1246bb0ec6b3SJim Harris uint8_t npss;
1247bb0ec6b3SJim Harris
1248bb0ec6b3SJim Harris /** admin vendor specific command configuration */
12490d787e9bSWojciech Macek uint8_t avscc;
1250bb0ec6b3SJim Harris
1251030edcceSWarner Losh /** Autonomous Power State Transition Attributes */
12520d787e9bSWojciech Macek uint8_t apsta;
1253030edcceSWarner Losh
1254030edcceSWarner Losh /** Warning Composite Temperature Threshold */
1255030edcceSWarner Losh uint16_t wctemp;
1256030edcceSWarner Losh
1257030edcceSWarner Losh /** Critical Composite Temperature Threshold */
1258030edcceSWarner Losh uint16_t cctemp;
1259030edcceSWarner Losh
1260030edcceSWarner Losh /** Maximum Time for Firmware Activation */
1261030edcceSWarner Losh uint16_t mtfa;
1262030edcceSWarner Losh
1263030edcceSWarner Losh /** Host Memory Buffer Preferred Size */
1264030edcceSWarner Losh uint32_t hmpre;
1265030edcceSWarner Losh
1266030edcceSWarner Losh /** Host Memory Buffer Minimum Size */
1267030edcceSWarner Losh uint32_t hmmin;
1268bb0ec6b3SJim Harris
1269594ffc03SWarner Losh /** Name space capabilities */
1270594ffc03SWarner Losh struct {
1271594ffc03SWarner Losh /* if nsmgmt, report tnvmcap and unvmcap */
1272594ffc03SWarner Losh uint8_t tnvmcap[16];
1273594ffc03SWarner Losh uint8_t unvmcap[16];
1274594ffc03SWarner Losh } __packed untncap;
1275594ffc03SWarner Losh
1276030edcceSWarner Losh /** Replay Protected Memory Block Support */
1277030edcceSWarner Losh uint32_t rpmbs; /* Really a bitfield */
1278030edcceSWarner Losh
1279030edcceSWarner Losh /** Extended Device Self-test Time */
1280030edcceSWarner Losh uint16_t edstt;
1281030edcceSWarner Losh
1282030edcceSWarner Losh /** Device Self-test Options */
1283030edcceSWarner Losh uint8_t dsto; /* Really a bitfield */
1284030edcceSWarner Losh
1285030edcceSWarner Losh /** Firmware Update Granularity */
1286030edcceSWarner Losh uint8_t fwug;
1287030edcceSWarner Losh
1288030edcceSWarner Losh /** Keep Alive Support */
1289030edcceSWarner Losh uint16_t kas;
1290030edcceSWarner Losh
1291030edcceSWarner Losh /** Host Controlled Thermal Management Attributes */
1292030edcceSWarner Losh uint16_t hctma; /* Really a bitfield */
1293030edcceSWarner Losh
1294030edcceSWarner Losh /** Minimum Thermal Management Temperature */
1295030edcceSWarner Losh uint16_t mntmt;
1296030edcceSWarner Losh
1297030edcceSWarner Losh /** Maximum Thermal Management Temperature */
1298030edcceSWarner Losh uint16_t mxtmt;
1299030edcceSWarner Losh
1300030edcceSWarner Losh /** Sanitize Capabilities */
1301030edcceSWarner Losh uint32_t sanicap; /* Really a bitfield */
1302030edcceSWarner Losh
13038de2d8c0SAlexander Motin /** Host Memory Buffer Minimum Descriptor Entry Size */
13048de2d8c0SAlexander Motin uint32_t hmminds;
13058de2d8c0SAlexander Motin
13068de2d8c0SAlexander Motin /** Host Memory Maximum Descriptors Entries */
13078de2d8c0SAlexander Motin uint16_t hmmaxd;
13088de2d8c0SAlexander Motin
13098de2d8c0SAlexander Motin /** NVM Set Identifier Maximum */
13108de2d8c0SAlexander Motin uint16_t nsetidmax;
13118de2d8c0SAlexander Motin
13128de2d8c0SAlexander Motin /** Endurance Group Identifier Maximum */
13138de2d8c0SAlexander Motin uint16_t endgidmax;
13148de2d8c0SAlexander Motin
13158de2d8c0SAlexander Motin /** ANA Transition Time */
13168de2d8c0SAlexander Motin uint8_t anatt;
13178de2d8c0SAlexander Motin
13188de2d8c0SAlexander Motin /** Asymmetric Namespace Access Capabilities */
13198de2d8c0SAlexander Motin uint8_t anacap;
13208de2d8c0SAlexander Motin
13218de2d8c0SAlexander Motin /** ANA Group Identifier Maximum */
13228de2d8c0SAlexander Motin uint32_t anagrpmax;
13238de2d8c0SAlexander Motin
13248de2d8c0SAlexander Motin /** Number of ANA Group Identifiers */
13258de2d8c0SAlexander Motin uint32_t nanagrpid;
13268de2d8c0SAlexander Motin
13278de2d8c0SAlexander Motin /** Persistent Event Log Size */
13288de2d8c0SAlexander Motin uint32_t pels;
13298de2d8c0SAlexander Motin
13308de2d8c0SAlexander Motin uint8_t reserved3[156];
1331bb0ec6b3SJim Harris /* bytes 512-703: nvm command set attributes */
1332bb0ec6b3SJim Harris
1333bb0ec6b3SJim Harris /** submission queue entry size */
13340d787e9bSWojciech Macek uint8_t sqes;
1335bb0ec6b3SJim Harris
1336bb0ec6b3SJim Harris /** completion queue entry size */
13370d787e9bSWojciech Macek uint8_t cqes;
1338bb0ec6b3SJim Harris
1339030edcceSWarner Losh /** Maximum Outstanding Commands */
1340030edcceSWarner Losh uint16_t maxcmd;
1341bb0ec6b3SJim Harris
1342bb0ec6b3SJim Harris /** number of namespaces */
1343bb0ec6b3SJim Harris uint32_t nn;
1344bb0ec6b3SJim Harris
1345bb0ec6b3SJim Harris /** optional nvm command support */
13460d787e9bSWojciech Macek uint16_t oncs;
1347bb0ec6b3SJim Harris
1348bb0ec6b3SJim Harris /** fused operation support */
1349bb0ec6b3SJim Harris uint16_t fuses;
1350bb0ec6b3SJim Harris
1351bb0ec6b3SJim Harris /** format nvm attributes */
1352bb0ec6b3SJim Harris uint8_t fna;
1353bb0ec6b3SJim Harris
1354bb0ec6b3SJim Harris /** volatile write cache */
13550d787e9bSWojciech Macek uint8_t vwc;
1356bb0ec6b3SJim Harris
13573fa5467aSAlexander Motin /** Atomic Write Unit Normal */
13583fa5467aSAlexander Motin uint16_t awun;
1359bb0ec6b3SJim Harris
13603fa5467aSAlexander Motin /** Atomic Write Unit Power Fail */
13613fa5467aSAlexander Motin uint16_t awupf;
13623fa5467aSAlexander Motin
13633fa5467aSAlexander Motin /** NVM Vendor Specific Command Configuration */
13643fa5467aSAlexander Motin uint8_t nvscc;
13658de2d8c0SAlexander Motin
13668de2d8c0SAlexander Motin /** Namespace Write Protection Capabilities */
13678de2d8c0SAlexander Motin uint8_t nwpc;
13683fa5467aSAlexander Motin
13693fa5467aSAlexander Motin /** Atomic Compare & Write Unit */
13703fa5467aSAlexander Motin uint16_t acwu;
13713fa5467aSAlexander Motin uint16_t reserved6;
13723fa5467aSAlexander Motin
13733fa5467aSAlexander Motin /** SGL Support */
13743fa5467aSAlexander Motin uint32_t sgls;
13753fa5467aSAlexander Motin
13768de2d8c0SAlexander Motin /** Maximum Number of Allowed Namespaces */
13778de2d8c0SAlexander Motin uint32_t mnan;
13788de2d8c0SAlexander Motin
13793fa5467aSAlexander Motin /* bytes 540-767: Reserved */
13808de2d8c0SAlexander Motin uint8_t reserved7[224];
13813fa5467aSAlexander Motin
13823fa5467aSAlexander Motin /** NVM Subsystem NVMe Qualified Name */
13833fa5467aSAlexander Motin uint8_t subnqn[256];
13843fa5467aSAlexander Motin
13853fa5467aSAlexander Motin /* bytes 1024-1791: Reserved */
13863fa5467aSAlexander Motin uint8_t reserved8[768];
13873fa5467aSAlexander Motin
13883fa5467aSAlexander Motin /* bytes 1792-2047: NVMe over Fabrics specification */
138921d3a84dSJohn Baldwin uint32_t ioccsz;
139021d3a84dSJohn Baldwin uint32_t iorcsz;
139121d3a84dSJohn Baldwin uint16_t icdoff;
139221d3a84dSJohn Baldwin uint8_t fcatt;
139321d3a84dSJohn Baldwin uint8_t msdbd;
139421d3a84dSJohn Baldwin uint16_t ofcs;
139521d3a84dSJohn Baldwin uint8_t reserved9[242];
1396bb0ec6b3SJim Harris
1397bb0ec6b3SJim Harris /* bytes 2048-3071: power state descriptors */
1398038659e7SWarner Losh struct nvme_power_state power_state[32];
1399bb0ec6b3SJim Harris
1400bb0ec6b3SJim Harris /* bytes 3072-4095: vendor specific */
1401a40e72a6SJim Harris uint8_t vs[1024];
1402be4dcf1bSJim Harris } __packed __aligned(4);
1403bb0ec6b3SJim Harris
14040012e436SWarner Losh _Static_assert(sizeof(struct nvme_controller_data) == 4096, "bad size for nvme_controller_data");
14050c26c199SWarner Losh
1406bb0ec6b3SJim Harris struct nvme_namespace_data {
1407bb0ec6b3SJim Harris /** namespace size */
1408bb0ec6b3SJim Harris uint64_t nsze;
1409bb0ec6b3SJim Harris
1410bb0ec6b3SJim Harris /** namespace capacity */
1411bb0ec6b3SJim Harris uint64_t ncap;
1412bb0ec6b3SJim Harris
1413bb0ec6b3SJim Harris /** namespace utilization */
1414bb0ec6b3SJim Harris uint64_t nuse;
1415bb0ec6b3SJim Harris
1416bb0ec6b3SJim Harris /** namespace features */
14170d787e9bSWojciech Macek uint8_t nsfeat;
1418bb0ec6b3SJim Harris
1419bb0ec6b3SJim Harris /** number of lba formats */
1420bb0ec6b3SJim Harris uint8_t nlbaf;
1421bb0ec6b3SJim Harris
1422bb0ec6b3SJim Harris /** formatted lba size */
14230d787e9bSWojciech Macek uint8_t flbas;
1424bb0ec6b3SJim Harris
1425bb0ec6b3SJim Harris /** metadata capabilities */
14260d787e9bSWojciech Macek uint8_t mc;
1427bb0ec6b3SJim Harris
1428bb0ec6b3SJim Harris /** end-to-end data protection capabilities */
14290d787e9bSWojciech Macek uint8_t dpc;
1430bb0ec6b3SJim Harris
1431bb0ec6b3SJim Harris /** end-to-end data protection type settings */
14320d787e9bSWojciech Macek uint8_t dps;
1433bb0ec6b3SJim Harris
14343fa5467aSAlexander Motin /** Namespace Multi-path I/O and Namespace Sharing Capabilities */
14353fa5467aSAlexander Motin uint8_t nmic;
14363fa5467aSAlexander Motin
14373fa5467aSAlexander Motin /** Reservation Capabilities */
14383fa5467aSAlexander Motin uint8_t rescap;
14393fa5467aSAlexander Motin
14403fa5467aSAlexander Motin /** Format Progress Indicator */
14413fa5467aSAlexander Motin uint8_t fpi;
14423fa5467aSAlexander Motin
14433fa5467aSAlexander Motin /** Deallocate Logical Block Features */
14443fa5467aSAlexander Motin uint8_t dlfeat;
14453fa5467aSAlexander Motin
14463fa5467aSAlexander Motin /** Namespace Atomic Write Unit Normal */
14473fa5467aSAlexander Motin uint16_t nawun;
14483fa5467aSAlexander Motin
14493fa5467aSAlexander Motin /** Namespace Atomic Write Unit Power Fail */
14503fa5467aSAlexander Motin uint16_t nawupf;
14513fa5467aSAlexander Motin
14523fa5467aSAlexander Motin /** Namespace Atomic Compare & Write Unit */
14533fa5467aSAlexander Motin uint16_t nacwu;
14543fa5467aSAlexander Motin
14553fa5467aSAlexander Motin /** Namespace Atomic Boundary Size Normal */
14563fa5467aSAlexander Motin uint16_t nabsn;
14573fa5467aSAlexander Motin
14583fa5467aSAlexander Motin /** Namespace Atomic Boundary Offset */
14593fa5467aSAlexander Motin uint16_t nabo;
14603fa5467aSAlexander Motin
14613fa5467aSAlexander Motin /** Namespace Atomic Boundary Size Power Fail */
14623fa5467aSAlexander Motin uint16_t nabspf;
14633fa5467aSAlexander Motin
14643fa5467aSAlexander Motin /** Namespace Optimal IO Boundary */
14653fa5467aSAlexander Motin uint16_t noiob;
14663fa5467aSAlexander Motin
14673fa5467aSAlexander Motin /** NVM Capacity */
14683fa5467aSAlexander Motin uint8_t nvmcap[16];
14693fa5467aSAlexander Motin
14708de2d8c0SAlexander Motin /** Namespace Preferred Write Granularity */
14718de2d8c0SAlexander Motin uint16_t npwg;
14728de2d8c0SAlexander Motin
14738de2d8c0SAlexander Motin /** Namespace Preferred Write Alignment */
14748de2d8c0SAlexander Motin uint16_t npwa;
14758de2d8c0SAlexander Motin
14768de2d8c0SAlexander Motin /** Namespace Preferred Deallocate Granularity */
14778de2d8c0SAlexander Motin uint16_t npdg;
14788de2d8c0SAlexander Motin
14798de2d8c0SAlexander Motin /** Namespace Preferred Deallocate Alignment */
14808de2d8c0SAlexander Motin uint16_t npda;
14818de2d8c0SAlexander Motin
14828de2d8c0SAlexander Motin /** Namespace Optimal Write Size */
14838de2d8c0SAlexander Motin uint16_t nows;
14848de2d8c0SAlexander Motin
14858de2d8c0SAlexander Motin /* bytes 74-91: Reserved */
14868de2d8c0SAlexander Motin uint8_t reserved5[18];
14878de2d8c0SAlexander Motin
14888de2d8c0SAlexander Motin /** ANA Group Identifier */
14898de2d8c0SAlexander Motin uint32_t anagrpid;
14908de2d8c0SAlexander Motin
14918de2d8c0SAlexander Motin /* bytes 96-98: Reserved */
14928de2d8c0SAlexander Motin uint8_t reserved6[3];
14938de2d8c0SAlexander Motin
14948de2d8c0SAlexander Motin /** Namespace Attributes */
14958de2d8c0SAlexander Motin uint8_t nsattr;
14968de2d8c0SAlexander Motin
14978de2d8c0SAlexander Motin /** NVM Set Identifier */
14988de2d8c0SAlexander Motin uint16_t nvmsetid;
14998de2d8c0SAlexander Motin
15008de2d8c0SAlexander Motin /** Endurance Group Identifier */
15018de2d8c0SAlexander Motin uint16_t endgid;
15023fa5467aSAlexander Motin
15033fa5467aSAlexander Motin /** Namespace Globally Unique Identifier */
15043fa5467aSAlexander Motin uint8_t nguid[16];
15053fa5467aSAlexander Motin
15063fa5467aSAlexander Motin /** IEEE Extended Unique Identifier */
15073fa5467aSAlexander Motin uint8_t eui64[8];
1508bb0ec6b3SJim Harris
1509bb0ec6b3SJim Harris /** lba format support */
15100d787e9bSWojciech Macek uint32_t lbaf[16];
1511bb0ec6b3SJim Harris
15128de2d8c0SAlexander Motin uint8_t reserved7[192];
1513bb0ec6b3SJim Harris
1514bb0ec6b3SJim Harris uint8_t vendor_specific[3712];
1515be4dcf1bSJim Harris } __packed __aligned(4);
1516bb0ec6b3SJim Harris
15170012e436SWarner Losh _Static_assert(sizeof(struct nvme_namespace_data) == 4096, "bad size for nvme_namepsace_data");
15180c26c199SWarner Losh
1519bb0ec6b3SJim Harris enum nvme_log_page {
1520bb0ec6b3SJim Harris /* 0x00 - reserved */
1521bb0ec6b3SJim Harris NVME_LOG_ERROR = 0x01,
1522bb0ec6b3SJim Harris NVME_LOG_HEALTH_INFORMATION = 0x02,
1523bb0ec6b3SJim Harris NVME_LOG_FIRMWARE_SLOT = 0x03,
1524aea52879SWarner Losh NVME_LOG_CHANGED_NAMESPACE = 0x04,
1525aea52879SWarner Losh NVME_LOG_COMMAND_EFFECT = 0x05,
152690dfa8f0SAlexander Motin NVME_LOG_DEVICE_SELF_TEST = 0x06,
152790dfa8f0SAlexander Motin NVME_LOG_TELEMETRY_HOST_INITIATED = 0x07,
152890dfa8f0SAlexander Motin NVME_LOG_TELEMETRY_CONTROLLER_INITIATED = 0x08,
152990dfa8f0SAlexander Motin NVME_LOG_ENDURANCE_GROUP_INFORMATION = 0x09,
153090dfa8f0SAlexander Motin NVME_LOG_PREDICTABLE_LATENCY_PER_NVM_SET = 0x0a,
153190dfa8f0SAlexander Motin NVME_LOG_PREDICTABLE_LATENCY_EVENT_AGGREGATE = 0x0b,
1532c2318cf8SChuck Tuffli NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS = 0x0c,
153390dfa8f0SAlexander Motin NVME_LOG_PERSISTENT_EVENT_LOG = 0x0d,
153490dfa8f0SAlexander Motin NVME_LOG_LBA_STATUS_INFORMATION = 0x0e,
153590dfa8f0SAlexander Motin NVME_LOG_ENDURANCE_GROUP_EVENT_AGGREGATE = 0x0f,
153688ecf154SJohn Baldwin NVME_LOG_DISCOVERY = 0x70,
1537aea52879SWarner Losh /* 0x06-0x7F - reserved */
1538bb0ec6b3SJim Harris /* 0x80-0xBF - I/O command set specific */
1539d01f26f5SWarner Losh NVME_LOG_RES_NOTIFICATION = 0x80,
154090dfa8f0SAlexander Motin NVME_LOG_SANITIZE_STATUS = 0x81,
154190dfa8f0SAlexander Motin /* 0x82-0xBF - reserved */
1542bb0ec6b3SJim Harris /* 0xC0-0xFF - vendor specific */
15430cf14228SWarner Losh
1544d01f26f5SWarner Losh /*
15450cf14228SWarner Losh * The following are Intel Specific log pages, but they seem
15460cf14228SWarner Losh * to be widely implemented.
1547d01f26f5SWarner Losh */
1548d01f26f5SWarner Losh INTEL_LOG_READ_LAT_LOG = 0xc1,
1549d01f26f5SWarner Losh INTEL_LOG_WRITE_LAT_LOG = 0xc2,
1550d01f26f5SWarner Losh INTEL_LOG_TEMP_STATS = 0xc5,
1551d01f26f5SWarner Losh INTEL_LOG_ADD_SMART = 0xca,
1552d01f26f5SWarner Losh INTEL_LOG_DRIVE_MKT_NAME = 0xdd,
1553d01f26f5SWarner Losh
15540cf14228SWarner Losh /*
15550cf14228SWarner Losh * HGST log page, with lots ofs sub pages.
15560cf14228SWarner Losh */
15570cf14228SWarner Losh HGST_INFO_LOG = 0xc1,
1558bb0ec6b3SJim Harris };
1559bb0ec6b3SJim Harris
156008927782SJim Harris struct nvme_error_information_entry {
156108927782SJim Harris uint64_t error_count;
156208927782SJim Harris uint16_t sqid;
156308927782SJim Harris uint16_t cid;
15640d787e9bSWojciech Macek uint16_t status;
156508927782SJim Harris uint16_t error_location;
156608927782SJim Harris uint64_t lba;
156708927782SJim Harris uint32_t nsid;
156808927782SJim Harris uint8_t vendor_specific;
156990dfa8f0SAlexander Motin uint8_t trtype;
157090dfa8f0SAlexander Motin uint16_t reserved30;
157190dfa8f0SAlexander Motin uint64_t csi;
157290dfa8f0SAlexander Motin uint16_t ttsi;
157390dfa8f0SAlexander Motin uint8_t reserved[22];
157408927782SJim Harris } __packed __aligned(4);
157508927782SJim Harris
15760012e436SWarner Losh _Static_assert(sizeof(struct nvme_error_information_entry) == 64, "bad size for nvme_error_information_entry");
15770c26c199SWarner Losh
1578bb0ec6b3SJim Harris struct nvme_health_information_page {
15790d787e9bSWojciech Macek uint8_t critical_warning;
1580bb0ec6b3SJim Harris uint16_t temperature;
1581bb0ec6b3SJim Harris uint8_t available_spare;
1582bb0ec6b3SJim Harris uint8_t available_spare_threshold;
1583bb0ec6b3SJim Harris uint8_t percentage_used;
1584bb0ec6b3SJim Harris
1585bb0ec6b3SJim Harris uint8_t reserved[26];
1586bb0ec6b3SJim Harris
1587bb0ec6b3SJim Harris /*
1588bb0ec6b3SJim Harris * Note that the following are 128-bit values, but are
1589bb0ec6b3SJim Harris * defined as an array of 2 64-bit values.
1590bb0ec6b3SJim Harris */
1591bb0ec6b3SJim Harris /* Data Units Read is always in 512-byte units. */
1592bb0ec6b3SJim Harris uint64_t data_units_read[2];
1593bb0ec6b3SJim Harris /* Data Units Written is always in 512-byte units. */
1594bb0ec6b3SJim Harris uint64_t data_units_written[2];
1595bb0ec6b3SJim Harris /* For NVM command set, this includes Compare commands. */
1596bb0ec6b3SJim Harris uint64_t host_read_commands[2];
1597bb0ec6b3SJim Harris uint64_t host_write_commands[2];
1598bb0ec6b3SJim Harris /* Controller Busy Time is reported in minutes. */
1599bb0ec6b3SJim Harris uint64_t controller_busy_time[2];
1600bb0ec6b3SJim Harris uint64_t power_cycles[2];
1601bb0ec6b3SJim Harris uint64_t power_on_hours[2];
1602bb0ec6b3SJim Harris uint64_t unsafe_shutdowns[2];
1603bb0ec6b3SJim Harris uint64_t media_errors[2];
1604bb0ec6b3SJim Harris uint64_t num_error_info_log_entries[2];
1605dc58cdf9SWarner Losh uint32_t warning_temp_time;
1606dc58cdf9SWarner Losh uint32_t error_temp_time;
1607dc58cdf9SWarner Losh uint16_t temp_sensor[8];
160890dfa8f0SAlexander Motin /* Thermal Management Temperature 1 Transition Count */
160990dfa8f0SAlexander Motin uint32_t tmt1tc;
161090dfa8f0SAlexander Motin /* Thermal Management Temperature 2 Transition Count */
161190dfa8f0SAlexander Motin uint32_t tmt2tc;
161290dfa8f0SAlexander Motin /* Total Time For Thermal Management Temperature 1 */
161390dfa8f0SAlexander Motin uint32_t ttftmt1;
161490dfa8f0SAlexander Motin /* Total Time For Thermal Management Temperature 2 */
161590dfa8f0SAlexander Motin uint32_t ttftmt2;
1616bb0ec6b3SJim Harris
161790dfa8f0SAlexander Motin uint8_t reserved2[280];
161829d7e39fSJohn Baldwin } __packed __aligned(8);
1619bb0ec6b3SJim Harris
16200012e436SWarner Losh _Static_assert(sizeof(struct nvme_health_information_page) == 512, "bad size for nvme_health_information_page");
16210c26c199SWarner Losh
16220692579bSJim Harris struct nvme_firmware_page {
16230d787e9bSWojciech Macek uint8_t afi;
16240692579bSJim Harris uint8_t reserved[7];
16257485926eSJohn Baldwin /* revisions for 7 slots */
16267485926eSJohn Baldwin uint8_t revision[7][NVME_FIRMWARE_REVISION_LENGTH];
16270692579bSJim Harris uint8_t reserved2[448];
1628ab1dd091SWarner Losh } __packed __aligned(4);
1629ab1dd091SWarner Losh
16300012e436SWarner Losh _Static_assert(sizeof(struct nvme_firmware_page) == 512, "bad size for nvme_firmware_page");
16310c26c199SWarner Losh
1632f439e3a4SAlexander Motin struct nvme_ns_list {
1633f439e3a4SAlexander Motin uint32_t ns[1024];
1634f439e3a4SAlexander Motin } __packed __aligned(4);
1635f439e3a4SAlexander Motin
1636f439e3a4SAlexander Motin _Static_assert(sizeof(struct nvme_ns_list) == 4096, "bad size for nvme_ns_list");
1637f439e3a4SAlexander Motin
16386c99d132SAlexander Motin struct nvme_command_effects_page {
16396c99d132SAlexander Motin uint32_t acs[256];
16406c99d132SAlexander Motin uint32_t iocs[256];
16416c99d132SAlexander Motin uint8_t reserved[2048];
16426c99d132SAlexander Motin } __packed __aligned(4);
16436c99d132SAlexander Motin
16446c99d132SAlexander Motin _Static_assert(sizeof(struct nvme_command_effects_page) == 4096,
16456c99d132SAlexander Motin "bad size for nvme_command_effects_page");
16466c99d132SAlexander Motin
164767334019SChuck Tuffli struct nvme_device_self_test_page {
164867334019SChuck Tuffli uint8_t curr_operation;
164967334019SChuck Tuffli uint8_t curr_compl;
165067334019SChuck Tuffli uint8_t rsvd2[2];
165167334019SChuck Tuffli struct {
165267334019SChuck Tuffli uint8_t status;
165367334019SChuck Tuffli uint8_t segment_num;
165467334019SChuck Tuffli uint8_t valid_diag_info;
165567334019SChuck Tuffli uint8_t rsvd3;
165667334019SChuck Tuffli uint64_t poh;
165767334019SChuck Tuffli uint32_t nsid;
165867334019SChuck Tuffli /* Define as an array to simplify alignment issues */
165967334019SChuck Tuffli uint8_t failing_lba[8];
166067334019SChuck Tuffli uint8_t status_code_type;
166167334019SChuck Tuffli uint8_t status_code;
166267334019SChuck Tuffli uint8_t vendor_specific[2];
166367334019SChuck Tuffli } __packed result[20];
166467334019SChuck Tuffli } __packed __aligned(4);
166567334019SChuck Tuffli
166667334019SChuck Tuffli _Static_assert(sizeof(struct nvme_device_self_test_page) == 564,
166767334019SChuck Tuffli "bad size for nvme_device_self_test_page");
166867334019SChuck Tuffli
1669e84a75f9SWarner Losh /*
1670e84a75f9SWarner Losh * Header structure for both host initiated telemetry (page 7) and controller
1671e84a75f9SWarner Losh * initiated telemetry (page 8).
1672e84a75f9SWarner Losh */
1673e84a75f9SWarner Losh struct nvme_telemetry_log_page {
1674e84a75f9SWarner Losh uint8_t identifier;
1675e84a75f9SWarner Losh uint8_t rsvd[4];
1676e84a75f9SWarner Losh uint8_t oui[3];
1677e84a75f9SWarner Losh uint16_t da1_last;
1678e84a75f9SWarner Losh uint16_t da2_last;
1679e84a75f9SWarner Losh uint16_t da3_last;
1680e84a75f9SWarner Losh uint8_t rsvd2[2];
1681e84a75f9SWarner Losh uint32_t da4_last;
1682e84a75f9SWarner Losh uint8_t rsvd3[361];
1683e84a75f9SWarner Losh uint8_t hi_gen;
1684e84a75f9SWarner Losh uint8_t ci_avail;
1685e84a75f9SWarner Losh uint8_t ci_gen;
1686e84a75f9SWarner Losh uint8_t reason[128];
1687e84a75f9SWarner Losh /* Blocks of telemetry data follow */
1688e84a75f9SWarner Losh } __packed __aligned(4);
1689e84a75f9SWarner Losh
1690e84a75f9SWarner Losh _Static_assert(sizeof(struct nvme_telemetry_log_page) == 512,
1691e84a75f9SWarner Losh "bad size for nvme_telemetry_log");
1692e84a75f9SWarner Losh
169388ecf154SJohn Baldwin struct nvme_discovery_log_entry {
169488ecf154SJohn Baldwin uint8_t trtype;
169588ecf154SJohn Baldwin uint8_t adrfam;
169688ecf154SJohn Baldwin uint8_t subtype;
169788ecf154SJohn Baldwin uint8_t treq;
169888ecf154SJohn Baldwin uint16_t portid;
169988ecf154SJohn Baldwin uint16_t cntlid;
170088ecf154SJohn Baldwin uint16_t aqsz;
170188ecf154SJohn Baldwin uint8_t reserved1[22];
170288ecf154SJohn Baldwin uint8_t trsvcid[32];
170388ecf154SJohn Baldwin uint8_t reserved2[192];
170488ecf154SJohn Baldwin uint8_t subnqn[256];
170588ecf154SJohn Baldwin uint8_t traddr[256];
170688ecf154SJohn Baldwin union {
170788ecf154SJohn Baldwin struct {
170888ecf154SJohn Baldwin uint8_t rdma_qptype;
170988ecf154SJohn Baldwin uint8_t rdma_prtype;
171088ecf154SJohn Baldwin uint8_t rdma_cms;
171188ecf154SJohn Baldwin uint8_t reserved[5];
171288ecf154SJohn Baldwin uint16_t rdma_pkey;
171388ecf154SJohn Baldwin } rdma;
171488ecf154SJohn Baldwin struct {
171588ecf154SJohn Baldwin uint8_t sectype;
171688ecf154SJohn Baldwin } tcp;
171788ecf154SJohn Baldwin uint8_t reserved[256];
171888ecf154SJohn Baldwin } tsas;
171988ecf154SJohn Baldwin } __packed __aligned(4);
172088ecf154SJohn Baldwin
172188ecf154SJohn Baldwin _Static_assert(sizeof(struct nvme_discovery_log_entry) == 1024,
172288ecf154SJohn Baldwin "bad size for nvme_discovery_log_entry");
172388ecf154SJohn Baldwin
172488ecf154SJohn Baldwin struct nvme_discovery_log {
172588ecf154SJohn Baldwin uint64_t genctr;
172688ecf154SJohn Baldwin uint64_t numrec;
172788ecf154SJohn Baldwin uint16_t recfmt;
172888ecf154SJohn Baldwin uint8_t reserved[1006];
172988ecf154SJohn Baldwin struct nvme_discovery_log_entry entries[];
173088ecf154SJohn Baldwin } __packed __aligned(4);
173188ecf154SJohn Baldwin
173288ecf154SJohn Baldwin _Static_assert(sizeof(struct nvme_discovery_log) == 1024,
173388ecf154SJohn Baldwin "bad size for nvme_discovery_log");
173488ecf154SJohn Baldwin
17356c99d132SAlexander Motin struct nvme_res_notification_page {
17366c99d132SAlexander Motin uint64_t log_page_count;
17376c99d132SAlexander Motin uint8_t log_page_type;
17386c99d132SAlexander Motin uint8_t available_log_pages;
17396c99d132SAlexander Motin uint8_t reserved2;
17406c99d132SAlexander Motin uint32_t nsid;
17416c99d132SAlexander Motin uint8_t reserved[48];
17426c99d132SAlexander Motin } __packed __aligned(4);
17436c99d132SAlexander Motin
17446c99d132SAlexander Motin _Static_assert(sizeof(struct nvme_res_notification_page) == 64,
17456c99d132SAlexander Motin "bad size for nvme_res_notification_page");
17466c99d132SAlexander Motin
17476c99d132SAlexander Motin struct nvme_sanitize_status_page {
17486c99d132SAlexander Motin uint16_t sprog;
17496c99d132SAlexander Motin uint16_t sstat;
17506c99d132SAlexander Motin uint32_t scdw10;
17516c99d132SAlexander Motin uint32_t etfo;
17526c99d132SAlexander Motin uint32_t etfbe;
17536c99d132SAlexander Motin uint32_t etfce;
17546c99d132SAlexander Motin uint32_t etfownd;
17556c99d132SAlexander Motin uint32_t etfbewnd;
17566c99d132SAlexander Motin uint32_t etfcewnd;
17576c99d132SAlexander Motin uint8_t reserved[480];
17586c99d132SAlexander Motin } __packed __aligned(4);
17596c99d132SAlexander Motin
17606c99d132SAlexander Motin _Static_assert(sizeof(struct nvme_sanitize_status_page) == 512,
17616c99d132SAlexander Motin "bad size for nvme_sanitize_status_page");
17626c99d132SAlexander Motin
176380a75155SWarner Losh struct intel_log_temp_stats {
1764ab1dd091SWarner Losh uint64_t current;
1765ab1dd091SWarner Losh uint64_t overtemp_flag_last;
1766ab1dd091SWarner Losh uint64_t overtemp_flag_life;
1767ab1dd091SWarner Losh uint64_t max_temp;
1768ab1dd091SWarner Losh uint64_t min_temp;
1769ab1dd091SWarner Losh uint64_t _rsvd[5];
1770ab1dd091SWarner Losh uint64_t max_oper_temp;
1771ab1dd091SWarner Losh uint64_t min_oper_temp;
1772ab1dd091SWarner Losh uint64_t est_offset;
17730692579bSJim Harris } __packed __aligned(4);
17740692579bSJim Harris
17750012e436SWarner Losh _Static_assert(sizeof(struct intel_log_temp_stats) == 13 * 8, "bad size for intel_log_temp_stats");
17760c26c199SWarner Losh
177780a75155SWarner Losh struct nvme_resv_reg_ctrlr {
177870d20ed3SAlexander Motin uint16_t ctrlr_id; /* Controller ID */
177970d20ed3SAlexander Motin uint8_t rcsts; /* Reservation Status */
178070d20ed3SAlexander Motin uint8_t reserved3[5];
178170d20ed3SAlexander Motin uint64_t hostid; /* Host Identifier */
178270d20ed3SAlexander Motin uint64_t rkey; /* Reservation Key */
178370d20ed3SAlexander Motin } __packed __aligned(4);
178470d20ed3SAlexander Motin
178570d20ed3SAlexander Motin _Static_assert(sizeof(struct nvme_resv_reg_ctrlr) == 24, "bad size for nvme_resv_reg_ctrlr");
178670d20ed3SAlexander Motin
178780a75155SWarner Losh struct nvme_resv_reg_ctrlr_ext {
178870d20ed3SAlexander Motin uint16_t ctrlr_id; /* Controller ID */
178970d20ed3SAlexander Motin uint8_t rcsts; /* Reservation Status */
179070d20ed3SAlexander Motin uint8_t reserved3[5];
179170d20ed3SAlexander Motin uint64_t rkey; /* Reservation Key */
179270d20ed3SAlexander Motin uint64_t hostid[2]; /* Host Identifier */
179370d20ed3SAlexander Motin uint8_t reserved32[32];
179470d20ed3SAlexander Motin } __packed __aligned(4);
179570d20ed3SAlexander Motin
179670d20ed3SAlexander Motin _Static_assert(sizeof(struct nvme_resv_reg_ctrlr_ext) == 64, "bad size for nvme_resv_reg_ctrlr_ext");
179770d20ed3SAlexander Motin
179880a75155SWarner Losh struct nvme_resv_status {
179970d20ed3SAlexander Motin uint32_t gen; /* Generation */
180070d20ed3SAlexander Motin uint8_t rtype; /* Reservation Type */
180170d20ed3SAlexander Motin uint8_t regctl[2]; /* Number of Registered Controllers */
180270d20ed3SAlexander Motin uint8_t reserved7[2];
180370d20ed3SAlexander Motin uint8_t ptpls; /* Persist Through Power Loss State */
180470d20ed3SAlexander Motin uint8_t reserved10[14];
180570d20ed3SAlexander Motin struct nvme_resv_reg_ctrlr ctrlr[0];
180670d20ed3SAlexander Motin } __packed __aligned(4);
180770d20ed3SAlexander Motin
180870d20ed3SAlexander Motin _Static_assert(sizeof(struct nvme_resv_status) == 24, "bad size for nvme_resv_status");
180970d20ed3SAlexander Motin
181080a75155SWarner Losh struct nvme_resv_status_ext {
181170d20ed3SAlexander Motin uint32_t gen; /* Generation */
181270d20ed3SAlexander Motin uint8_t rtype; /* Reservation Type */
181370d20ed3SAlexander Motin uint8_t regctl[2]; /* Number of Registered Controllers */
181470d20ed3SAlexander Motin uint8_t reserved7[2];
181570d20ed3SAlexander Motin uint8_t ptpls; /* Persist Through Power Loss State */
181670d20ed3SAlexander Motin uint8_t reserved10[14];
181770d20ed3SAlexander Motin uint8_t reserved24[40];
181870d20ed3SAlexander Motin struct nvme_resv_reg_ctrlr_ext ctrlr[0];
181970d20ed3SAlexander Motin } __packed __aligned(4);
182070d20ed3SAlexander Motin
182170d20ed3SAlexander Motin _Static_assert(sizeof(struct nvme_resv_status_ext) == 64, "bad size for nvme_resv_status_ext");
182270d20ed3SAlexander Motin
1823bb0ec6b3SJim Harris #define NVME_TEST_MAX_THREADS 128
1824bb0ec6b3SJim Harris
1825bb0ec6b3SJim Harris struct nvme_io_test {
1826bb0ec6b3SJim Harris enum nvme_nvm_opcode opc;
1827bb0ec6b3SJim Harris uint32_t size;
1828bb0ec6b3SJim Harris uint32_t time; /* in seconds */
1829bb0ec6b3SJim Harris uint32_t num_threads;
1830bb0ec6b3SJim Harris uint32_t flags;
1831992db80fSJim Harris uint64_t io_completed[NVME_TEST_MAX_THREADS];
1832bb0ec6b3SJim Harris };
1833bb0ec6b3SJim Harris
1834bb0ec6b3SJim Harris enum nvme_io_test_flags {
1835bb0ec6b3SJim Harris /*
1836bb0ec6b3SJim Harris * Specifies whether dev_refthread/dev_relthread should be
1837bb0ec6b3SJim Harris * called during NVME_BIO_TEST. Ignored for other test
1838bb0ec6b3SJim Harris * types.
1839bb0ec6b3SJim Harris */
1840bb0ec6b3SJim Harris NVME_TEST_FLAG_REFTHREAD = 0x1,
1841bb0ec6b3SJim Harris };
1842bb0ec6b3SJim Harris
18437c3f19d7SJim Harris struct nvme_pt_command {
18447c3f19d7SJim Harris /*
18457c3f19d7SJim Harris * cmd is used to specify a passthrough command to a controller or
18467c3f19d7SJim Harris * namespace.
18477c3f19d7SJim Harris *
18487c3f19d7SJim Harris * The following fields from cmd may be specified by the caller:
18497c3f19d7SJim Harris * * opc (opcode)
18507c3f19d7SJim Harris * * nsid (namespace id) - for admin commands only
18517c3f19d7SJim Harris * * cdw10-cdw15
18527c3f19d7SJim Harris *
18537c3f19d7SJim Harris * Remaining fields must be set to 0 by the caller.
18547c3f19d7SJim Harris */
18557c3f19d7SJim Harris struct nvme_command cmd;
18567c3f19d7SJim Harris
18577c3f19d7SJim Harris /*
18587c3f19d7SJim Harris * cpl returns completion status for the passthrough command
18597c3f19d7SJim Harris * specified by cmd.
18607c3f19d7SJim Harris *
18617c3f19d7SJim Harris * The following fields will be filled out by the driver, for
18627c3f19d7SJim Harris * consumption by the caller:
18637c3f19d7SJim Harris * * cdw0
18647c3f19d7SJim Harris * * status (except for phase)
18657c3f19d7SJim Harris *
18667c3f19d7SJim Harris * Remaining fields will be set to 0 by the driver.
18677c3f19d7SJim Harris */
18687c3f19d7SJim Harris struct nvme_completion cpl;
18697c3f19d7SJim Harris
18707c3f19d7SJim Harris /* buf is the data buffer associated with this passthrough command. */
18717c3f19d7SJim Harris void * buf;
18727c3f19d7SJim Harris
18737c3f19d7SJim Harris /*
18747c3f19d7SJim Harris * len is the length of the data buffer associated with this
18757c3f19d7SJim Harris * passthrough command.
18767c3f19d7SJim Harris */
18777c3f19d7SJim Harris uint32_t len;
18787c3f19d7SJim Harris
18797c3f19d7SJim Harris /*
18807c3f19d7SJim Harris * is_read = 1 if the passthrough command will read data into the
188166619178SJim Harris * supplied buffer from the controller.
18827c3f19d7SJim Harris *
188366619178SJim Harris * is_read = 0 if the passthrough command will write data from the
188466619178SJim Harris * supplied buffer to the controller.
18857c3f19d7SJim Harris */
18867c3f19d7SJim Harris uint32_t is_read;
18877c3f19d7SJim Harris
18887c3f19d7SJim Harris /*
18897c3f19d7SJim Harris * driver_lock is used by the driver only. It must be set to 0
18907c3f19d7SJim Harris * by the caller.
18917c3f19d7SJim Harris */
18927c3f19d7SJim Harris struct mtx * driver_lock;
18937c3f19d7SJim Harris };
18947c3f19d7SJim Harris
1895a7bf63beSAlexander Motin struct nvme_get_nsid {
1896a7bf63beSAlexander Motin char cdev[SPECNAMELEN + 1];
1897a7bf63beSAlexander Motin uint32_t nsid;
1898a7bf63beSAlexander Motin };
1899a7bf63beSAlexander Motin
190067abaee9SAlexander Motin struct nvme_hmb_desc {
190167abaee9SAlexander Motin uint64_t addr;
190267abaee9SAlexander Motin uint32_t size;
190367abaee9SAlexander Motin uint32_t reserved;
190467abaee9SAlexander Motin };
190567abaee9SAlexander Motin
1906cf81529cSJim Harris #define nvme_completion_is_error(cpl) \
19070d787e9bSWojciech Macek (NVME_STATUS_GET_SC((cpl)->status) != 0 || NVME_STATUS_GET_SCT((cpl)->status) != 0)
1908cf81529cSJim Harris
1909*7b3ee39eSJohn Baldwin void nvme_cpl_sbuf(const struct nvme_completion *cpl, struct sbuf *sbuf);
1910*7b3ee39eSJohn Baldwin void nvme_opcode_sbuf(bool admin, uint8_t opc, struct sbuf *sb);
1911*7b3ee39eSJohn Baldwin void nvme_sc_sbuf(const struct nvme_completion *cpl, struct sbuf *sbuf);
191238441bd9SJim Harris void nvme_strvis(uint8_t *dst, const uint8_t *src, int dstlen, int srclen);
191338441bd9SJim Harris
1914bb0ec6b3SJim Harris #ifdef _KERNEL
1915bb0ec6b3SJim Harris
1916bb0ec6b3SJim Harris struct bio;
1917a7bf63beSAlexander Motin struct thread;
1918bb0ec6b3SJim Harris
1919bb0ec6b3SJim Harris struct nvme_namespace;
1920038a5ee4SJim Harris struct nvme_controller;
1921bb0ec6b3SJim Harris struct nvme_consumer;
19221bce7cd8SWarner Losh struct nvme_passthru_cmd;
1923bb0ec6b3SJim Harris
1924bb0ec6b3SJim Harris typedef void (*nvme_cb_fn_t)(void *, const struct nvme_completion *);
1925038a5ee4SJim Harris
1926038a5ee4SJim Harris typedef void *(*nvme_cons_ns_fn_t)(struct nvme_namespace *, void *);
1927038a5ee4SJim Harris typedef void *(*nvme_cons_ctrlr_fn_t)(struct nvme_controller *);
19280d7e13ecSJim Harris typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *,
19290d7e13ecSJim Harris uint32_t, void *, uint32_t);
1930232e2edbSJim Harris typedef void (*nvme_cons_fail_fn_t)(void *);
1931bb0ec6b3SJim Harris
1932bb0ec6b3SJim Harris enum nvme_namespace_flags {
1933bb0ec6b3SJim Harris NVME_NS_DEALLOCATE_SUPPORTED = 0x1,
1934bb0ec6b3SJim Harris NVME_NS_FLUSH_SUPPORTED = 0x2,
1935bb0ec6b3SJim Harris };
1936bb0ec6b3SJim Harris
19377c3f19d7SJim Harris int nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctrlr,
19387c3f19d7SJim Harris struct nvme_pt_command *pt,
19397c3f19d7SJim Harris uint32_t nsid, int is_user_buffer,
19407c3f19d7SJim Harris int is_admin_cmd);
19417c3f19d7SJim Harris
19421bce7cd8SWarner Losh int nvme_ctrlr_linux_passthru_cmd(struct nvme_controller *ctrlr,
19431bce7cd8SWarner Losh struct nvme_passthru_cmd *npc,
19441bce7cd8SWarner Losh uint32_t nsid, bool is_user,
19451bce7cd8SWarner Losh bool is_admin);
19461bce7cd8SWarner Losh
194799d99f74SJim Harris /* Admin functions */
194899d99f74SJim Harris void nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr,
194999d99f74SJim Harris uint8_t feature, uint32_t cdw11,
195067abaee9SAlexander Motin uint32_t cdw12, uint32_t cdw13,
195167abaee9SAlexander Motin uint32_t cdw14, uint32_t cdw15,
195299d99f74SJim Harris void *payload, uint32_t payload_size,
195399d99f74SJim Harris nvme_cb_fn_t cb_fn, void *cb_arg);
195499d99f74SJim Harris void nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr,
195599d99f74SJim Harris uint8_t feature, uint32_t cdw11,
195699d99f74SJim Harris void *payload, uint32_t payload_size,
195799d99f74SJim Harris nvme_cb_fn_t cb_fn, void *cb_arg);
19585f1e251dSJim Harris void nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr,
19595f1e251dSJim Harris uint8_t log_page, uint32_t nsid,
19605f1e251dSJim Harris void *payload, uint32_t payload_size,
19615f1e251dSJim Harris nvme_cb_fn_t cb_fn, void *cb_arg);
196299d99f74SJim Harris
1963bb0ec6b3SJim Harris /* NVM I/O functions */
19649eb93f29SJim Harris int nvme_ns_cmd_write(struct nvme_namespace *ns, void *payload,
1965bb0ec6b3SJim Harris uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
1966bb0ec6b3SJim Harris void *cb_arg);
19675fdf9c3cSJim Harris int nvme_ns_cmd_write_bio(struct nvme_namespace *ns, struct bio *bp,
19685fdf9c3cSJim Harris nvme_cb_fn_t cb_fn, void *cb_arg);
19699eb93f29SJim Harris int nvme_ns_cmd_read(struct nvme_namespace *ns, void *payload,
1970bb0ec6b3SJim Harris uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
1971bb0ec6b3SJim Harris void *cb_arg);
19725fdf9c3cSJim Harris int nvme_ns_cmd_read_bio(struct nvme_namespace *ns, struct bio *bp,
19735fdf9c3cSJim Harris nvme_cb_fn_t cb_fn, void *cb_arg);
19749eb93f29SJim Harris int nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
1975bb0ec6b3SJim Harris uint8_t num_ranges, nvme_cb_fn_t cb_fn,
1976bb0ec6b3SJim Harris void *cb_arg);
19779eb93f29SJim Harris int nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
1978bb0ec6b3SJim Harris void *cb_arg);
1979a498975eSScott Long int nvme_ns_dump(struct nvme_namespace *ns, void *virt, off_t offset,
1980a498975eSScott Long size_t len);
1981bb0ec6b3SJim Harris
1982bb0ec6b3SJim Harris /* Registration functions */
1983038a5ee4SJim Harris struct nvme_consumer * nvme_register_consumer(nvme_cons_ns_fn_t ns_fn,
1984038a5ee4SJim Harris nvme_cons_ctrlr_fn_t ctrlr_fn,
1985232e2edbSJim Harris nvme_cons_async_fn_t async_fn,
1986232e2edbSJim Harris nvme_cons_fail_fn_t fail_fn);
1987bb0ec6b3SJim Harris void nvme_unregister_consumer(struct nvme_consumer *consumer);
1988bb0ec6b3SJim Harris
1989038a5ee4SJim Harris /* Controller helper functions */
1990038a5ee4SJim Harris device_t nvme_ctrlr_get_device(struct nvme_controller *ctrlr);
1991dbba7442SJim Harris const struct nvme_controller_data *
1992dbba7442SJim Harris nvme_ctrlr_get_data(struct nvme_controller *ctrlr);
199387b3975eSChuck Tuffli static inline bool
nvme_ctrlr_has_dataset_mgmt(const struct nvme_controller_data * cd)199487b3975eSChuck Tuffli nvme_ctrlr_has_dataset_mgmt(const struct nvme_controller_data *cd)
199587b3975eSChuck Tuffli {
199687b3975eSChuck Tuffli /* Assumes cd was byte swapped by nvme_controller_data_swapbytes() */
1997479680f2SJohn Baldwin return (NVMEV(NVME_CTRLR_DATA_ONCS_DSM, cd->oncs) != 0);
199887b3975eSChuck Tuffli }
1999038a5ee4SJim Harris
2000bb0ec6b3SJim Harris /* Namespace helper functions */
2001bb0ec6b3SJim Harris uint32_t nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns);
2002bb0ec6b3SJim Harris uint32_t nvme_ns_get_sector_size(struct nvme_namespace *ns);
2003bb0ec6b3SJim Harris uint64_t nvme_ns_get_num_sectors(struct nvme_namespace *ns);
2004bb0ec6b3SJim Harris uint64_t nvme_ns_get_size(struct nvme_namespace *ns);
2005bb0ec6b3SJim Harris uint32_t nvme_ns_get_flags(struct nvme_namespace *ns);
2006bb0ec6b3SJim Harris const char * nvme_ns_get_serial_number(struct nvme_namespace *ns);
2007bb0ec6b3SJim Harris const char * nvme_ns_get_model_number(struct nvme_namespace *ns);
2008dbba7442SJim Harris const struct nvme_namespace_data *
2009dbba7442SJim Harris nvme_ns_get_data(struct nvme_namespace *ns);
2010fdbd3d80SJim Harris uint32_t nvme_ns_get_stripesize(struct nvme_namespace *ns);
2011bb0ec6b3SJim Harris
2012bb0ec6b3SJim Harris int nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
2013bb0ec6b3SJim Harris nvme_cb_fn_t cb_fn);
2014a7bf63beSAlexander Motin int nvme_ns_ioctl_process(struct nvme_namespace *ns, u_long cmd,
2015a7bf63beSAlexander Motin caddr_t arg, int flag, struct thread *td);
2016bb0ec6b3SJim Harris
2017fa271a5dSWarner Losh /*
2018fa271a5dSWarner Losh * Command building helper functions -- shared with CAM
2019fa271a5dSWarner Losh * These functions assume allocator zeros out cmd structure
2020fa271a5dSWarner Losh * CAM's xpt_get_ccb and the request allocator for nvme both
2021fa271a5dSWarner Losh * do zero'd allocations.
2022fa271a5dSWarner Losh */
2023f24c011bSWarner Losh static inline
nvme_ns_flush_cmd(struct nvme_command * cmd,uint32_t nsid)2024c2005bbaSWarner Losh void nvme_ns_flush_cmd(struct nvme_command *cmd, uint32_t nsid)
2025f24c011bSWarner Losh {
2026f24c011bSWarner Losh
20279544e6dcSChuck Tuffli cmd->opc = NVME_OPC_FLUSH;
20280d787e9bSWojciech Macek cmd->nsid = htole32(nsid);
2029f24c011bSWarner Losh }
2030f24c011bSWarner Losh
2031f24c011bSWarner Losh static inline
nvme_ns_rw_cmd(struct nvme_command * cmd,uint32_t rwcmd,uint32_t nsid,uint64_t lba,uint32_t count)2032c2005bbaSWarner Losh void nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint32_t nsid,
2033f24c011bSWarner Losh uint64_t lba, uint32_t count)
2034f24c011bSWarner Losh {
20359544e6dcSChuck Tuffli cmd->opc = rwcmd;
20360d787e9bSWojciech Macek cmd->nsid = htole32(nsid);
20370d787e9bSWojciech Macek cmd->cdw10 = htole32(lba & 0xffffffffu);
20380d787e9bSWojciech Macek cmd->cdw11 = htole32(lba >> 32);
20390d787e9bSWojciech Macek cmd->cdw12 = htole32(count-1);
2040f24c011bSWarner Losh }
2041f24c011bSWarner Losh
2042f24c011bSWarner Losh static inline
nvme_ns_write_cmd(struct nvme_command * cmd,uint32_t nsid,uint64_t lba,uint32_t count)2043c2005bbaSWarner Losh void nvme_ns_write_cmd(struct nvme_command *cmd, uint32_t nsid,
2044f24c011bSWarner Losh uint64_t lba, uint32_t count)
2045f24c011bSWarner Losh {
2046f24c011bSWarner Losh nvme_ns_rw_cmd(cmd, NVME_OPC_WRITE, nsid, lba, count);
2047f24c011bSWarner Losh }
2048f24c011bSWarner Losh
2049f24c011bSWarner Losh static inline
nvme_ns_read_cmd(struct nvme_command * cmd,uint32_t nsid,uint64_t lba,uint32_t count)2050c2005bbaSWarner Losh void nvme_ns_read_cmd(struct nvme_command *cmd, uint32_t nsid,
2051f24c011bSWarner Losh uint64_t lba, uint32_t count)
2052f24c011bSWarner Losh {
2053f24c011bSWarner Losh nvme_ns_rw_cmd(cmd, NVME_OPC_READ, nsid, lba, count);
2054f24c011bSWarner Losh }
2055f24c011bSWarner Losh
2056f24c011bSWarner Losh static inline
nvme_ns_trim_cmd(struct nvme_command * cmd,uint32_t nsid,uint32_t num_ranges)2057c2005bbaSWarner Losh void nvme_ns_trim_cmd(struct nvme_command *cmd, uint32_t nsid,
2058f24c011bSWarner Losh uint32_t num_ranges)
2059f24c011bSWarner Losh {
20609544e6dcSChuck Tuffli cmd->opc = NVME_OPC_DATASET_MANAGEMENT;
20610d787e9bSWojciech Macek cmd->nsid = htole32(nsid);
20620d787e9bSWojciech Macek cmd->cdw10 = htole32(num_ranges - 1);
20630d787e9bSWojciech Macek cmd->cdw11 = htole32(NVME_DSM_ATTR_DEALLOCATE);
2064f24c011bSWarner Losh }
2065f24c011bSWarner Losh
20668a5d94f9SWarner Losh extern int nvme_use_nvd;
20678a5d94f9SWarner Losh
2068bb0ec6b3SJim Harris #endif /* _KERNEL */
2069bb0ec6b3SJim Harris
20700d787e9bSWojciech Macek /* Endianess conversion functions for NVMe structs */
20710d787e9bSWojciech Macek static inline
nvme_completion_swapbytes(struct nvme_completion * s __unused)2072cf7c0629SMichal Meloun void nvme_completion_swapbytes(struct nvme_completion *s __unused)
20730d787e9bSWojciech Macek {
207452a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
20750d787e9bSWojciech Macek
20760d787e9bSWojciech Macek s->cdw0 = le32toh(s->cdw0);
20770d787e9bSWojciech Macek /* omit rsvd1 */
20780d787e9bSWojciech Macek s->sqhd = le16toh(s->sqhd);
20790d787e9bSWojciech Macek s->sqid = le16toh(s->sqid);
20800d787e9bSWojciech Macek /* omit cid */
20810d787e9bSWojciech Macek s->status = le16toh(s->status);
208252a83207SMichal Meloun #endif
20830d787e9bSWojciech Macek }
20840d787e9bSWojciech Macek
20850d787e9bSWojciech Macek static inline
nvme_power_state_swapbytes(struct nvme_power_state * s __unused)2086cf7c0629SMichal Meloun void nvme_power_state_swapbytes(struct nvme_power_state *s __unused)
20870d787e9bSWojciech Macek {
208852a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
20890d787e9bSWojciech Macek
20900d787e9bSWojciech Macek s->mp = le16toh(s->mp);
20910d787e9bSWojciech Macek s->enlat = le32toh(s->enlat);
20920d787e9bSWojciech Macek s->exlat = le32toh(s->exlat);
20930d787e9bSWojciech Macek s->idlp = le16toh(s->idlp);
20940d787e9bSWojciech Macek s->actp = le16toh(s->actp);
209552a83207SMichal Meloun #endif
20960d787e9bSWojciech Macek }
20970d787e9bSWojciech Macek
20980d787e9bSWojciech Macek static inline
nvme_controller_data_swapbytes(struct nvme_controller_data * s __unused)2099cf7c0629SMichal Meloun void nvme_controller_data_swapbytes(struct nvme_controller_data *s __unused)
21000d787e9bSWojciech Macek {
210152a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
21020d787e9bSWojciech Macek int i;
21030d787e9bSWojciech Macek
21040d787e9bSWojciech Macek s->vid = le16toh(s->vid);
21050d787e9bSWojciech Macek s->ssvid = le16toh(s->ssvid);
21060d787e9bSWojciech Macek s->ctrlr_id = le16toh(s->ctrlr_id);
21070d787e9bSWojciech Macek s->ver = le32toh(s->ver);
21080d787e9bSWojciech Macek s->rtd3r = le32toh(s->rtd3r);
21090d787e9bSWojciech Macek s->rtd3e = le32toh(s->rtd3e);
21100d787e9bSWojciech Macek s->oaes = le32toh(s->oaes);
21110d787e9bSWojciech Macek s->ctratt = le32toh(s->ctratt);
21128de2d8c0SAlexander Motin s->rrls = le16toh(s->rrls);
21138de2d8c0SAlexander Motin s->crdt1 = le16toh(s->crdt1);
21148de2d8c0SAlexander Motin s->crdt2 = le16toh(s->crdt2);
21158de2d8c0SAlexander Motin s->crdt3 = le16toh(s->crdt3);
21160d787e9bSWojciech Macek s->oacs = le16toh(s->oacs);
21170d787e9bSWojciech Macek s->wctemp = le16toh(s->wctemp);
21180d787e9bSWojciech Macek s->cctemp = le16toh(s->cctemp);
21190d787e9bSWojciech Macek s->mtfa = le16toh(s->mtfa);
21200d787e9bSWojciech Macek s->hmpre = le32toh(s->hmpre);
21210d787e9bSWojciech Macek s->hmmin = le32toh(s->hmmin);
21220d787e9bSWojciech Macek s->rpmbs = le32toh(s->rpmbs);
21230d787e9bSWojciech Macek s->edstt = le16toh(s->edstt);
21240d787e9bSWojciech Macek s->kas = le16toh(s->kas);
21250d787e9bSWojciech Macek s->hctma = le16toh(s->hctma);
21260d787e9bSWojciech Macek s->mntmt = le16toh(s->mntmt);
21270d787e9bSWojciech Macek s->mxtmt = le16toh(s->mxtmt);
21280d787e9bSWojciech Macek s->sanicap = le32toh(s->sanicap);
21298de2d8c0SAlexander Motin s->hmminds = le32toh(s->hmminds);
21308de2d8c0SAlexander Motin s->hmmaxd = le16toh(s->hmmaxd);
21318de2d8c0SAlexander Motin s->nsetidmax = le16toh(s->nsetidmax);
21328de2d8c0SAlexander Motin s->endgidmax = le16toh(s->endgidmax);
21338de2d8c0SAlexander Motin s->anagrpmax = le32toh(s->anagrpmax);
21348de2d8c0SAlexander Motin s->nanagrpid = le32toh(s->nanagrpid);
21358de2d8c0SAlexander Motin s->pels = le32toh(s->pels);
21360d787e9bSWojciech Macek s->maxcmd = le16toh(s->maxcmd);
21370d787e9bSWojciech Macek s->nn = le32toh(s->nn);
21380d787e9bSWojciech Macek s->oncs = le16toh(s->oncs);
21390d787e9bSWojciech Macek s->fuses = le16toh(s->fuses);
21403fa5467aSAlexander Motin s->awun = le16toh(s->awun);
21413fa5467aSAlexander Motin s->awupf = le16toh(s->awupf);
21423fa5467aSAlexander Motin s->acwu = le16toh(s->acwu);
21433fa5467aSAlexander Motin s->sgls = le32toh(s->sgls);
21448de2d8c0SAlexander Motin s->mnan = le32toh(s->mnan);
214521d3a84dSJohn Baldwin s->ioccsz = le32toh(s->ioccsz);
214621d3a84dSJohn Baldwin s->iorcsz = le32toh(s->iorcsz);
214721d3a84dSJohn Baldwin s->icdoff = le16toh(s->icdoff);
214821d3a84dSJohn Baldwin s->ofcs = le16toh(s->ofcs);
21490d787e9bSWojciech Macek for (i = 0; i < 32; i++)
21500d787e9bSWojciech Macek nvme_power_state_swapbytes(&s->power_state[i]);
215152a83207SMichal Meloun #endif
21520d787e9bSWojciech Macek }
21530d787e9bSWojciech Macek
21540d787e9bSWojciech Macek static inline
nvme_namespace_data_swapbytes(struct nvme_namespace_data * s __unused)2155cf7c0629SMichal Meloun void nvme_namespace_data_swapbytes(struct nvme_namespace_data *s __unused)
21560d787e9bSWojciech Macek {
215752a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
21580d787e9bSWojciech Macek int i;
21590d787e9bSWojciech Macek
21600d787e9bSWojciech Macek s->nsze = le64toh(s->nsze);
21610d787e9bSWojciech Macek s->ncap = le64toh(s->ncap);
21620d787e9bSWojciech Macek s->nuse = le64toh(s->nuse);
21633fa5467aSAlexander Motin s->nawun = le16toh(s->nawun);
21643fa5467aSAlexander Motin s->nawupf = le16toh(s->nawupf);
21653fa5467aSAlexander Motin s->nacwu = le16toh(s->nacwu);
21663fa5467aSAlexander Motin s->nabsn = le16toh(s->nabsn);
21673fa5467aSAlexander Motin s->nabo = le16toh(s->nabo);
21683fa5467aSAlexander Motin s->nabspf = le16toh(s->nabspf);
21693fa5467aSAlexander Motin s->noiob = le16toh(s->noiob);
21708de2d8c0SAlexander Motin s->npwg = le16toh(s->npwg);
21718de2d8c0SAlexander Motin s->npwa = le16toh(s->npwa);
21728de2d8c0SAlexander Motin s->npdg = le16toh(s->npdg);
21738de2d8c0SAlexander Motin s->npda = le16toh(s->npda);
21748de2d8c0SAlexander Motin s->nows = le16toh(s->nows);
21758de2d8c0SAlexander Motin s->anagrpid = le32toh(s->anagrpid);
21768de2d8c0SAlexander Motin s->nvmsetid = le16toh(s->nvmsetid);
21778de2d8c0SAlexander Motin s->endgid = le16toh(s->endgid);
21780d787e9bSWojciech Macek for (i = 0; i < 16; i++)
21790d787e9bSWojciech Macek s->lbaf[i] = le32toh(s->lbaf[i]);
218052a83207SMichal Meloun #endif
21810d787e9bSWojciech Macek }
21820d787e9bSWojciech Macek
21830d787e9bSWojciech Macek static inline
nvme_error_information_entry_swapbytes(struct nvme_error_information_entry * s __unused)2184b2e9e573SMichal Meloun void nvme_error_information_entry_swapbytes(
2185cf7c0629SMichal Meloun struct nvme_error_information_entry *s __unused)
21860d787e9bSWojciech Macek {
218752a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
21880d787e9bSWojciech Macek
21890d787e9bSWojciech Macek s->error_count = le64toh(s->error_count);
21900d787e9bSWojciech Macek s->sqid = le16toh(s->sqid);
21910d787e9bSWojciech Macek s->cid = le16toh(s->cid);
21920d787e9bSWojciech Macek s->status = le16toh(s->status);
21930d787e9bSWojciech Macek s->error_location = le16toh(s->error_location);
21940d787e9bSWojciech Macek s->lba = le64toh(s->lba);
21950d787e9bSWojciech Macek s->nsid = le32toh(s->nsid);
219690dfa8f0SAlexander Motin s->csi = le64toh(s->csi);
219790dfa8f0SAlexander Motin s->ttsi = le16toh(s->ttsi);
219852a83207SMichal Meloun #endif
21990d787e9bSWojciech Macek }
22000d787e9bSWojciech Macek
22010d787e9bSWojciech Macek static inline
nvme_le128toh(void * p __unused)2202cf7c0629SMichal Meloun void nvme_le128toh(void *p __unused)
22030d787e9bSWojciech Macek {
22040d787e9bSWojciech Macek #if _BYTE_ORDER != _LITTLE_ENDIAN
22050d787e9bSWojciech Macek /* Swap 16 bytes in place */
22060d787e9bSWojciech Macek char *tmp = (char*)p;
22070d787e9bSWojciech Macek char b;
22080d787e9bSWojciech Macek int i;
22090d787e9bSWojciech Macek for (i = 0; i < 8; i++) {
22100d787e9bSWojciech Macek b = tmp[i];
22110d787e9bSWojciech Macek tmp[i] = tmp[15-i];
22120d787e9bSWojciech Macek tmp[15-i] = b;
22130d787e9bSWojciech Macek }
22140d787e9bSWojciech Macek #endif
22150d787e9bSWojciech Macek }
22160d787e9bSWojciech Macek
22170d787e9bSWojciech Macek static inline
nvme_health_information_page_swapbytes(struct nvme_health_information_page * s __unused)2218b2e9e573SMichal Meloun void nvme_health_information_page_swapbytes(
2219cf7c0629SMichal Meloun struct nvme_health_information_page *s __unused)
22200d787e9bSWojciech Macek {
222152a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
22220d787e9bSWojciech Macek int i;
22230d787e9bSWojciech Macek
22240d787e9bSWojciech Macek s->temperature = le16toh(s->temperature);
22250d787e9bSWojciech Macek nvme_le128toh((void *)s->data_units_read);
22260d787e9bSWojciech Macek nvme_le128toh((void *)s->data_units_written);
22270d787e9bSWojciech Macek nvme_le128toh((void *)s->host_read_commands);
22280d787e9bSWojciech Macek nvme_le128toh((void *)s->host_write_commands);
22290d787e9bSWojciech Macek nvme_le128toh((void *)s->controller_busy_time);
22300d787e9bSWojciech Macek nvme_le128toh((void *)s->power_cycles);
22310d787e9bSWojciech Macek nvme_le128toh((void *)s->power_on_hours);
22320d787e9bSWojciech Macek nvme_le128toh((void *)s->unsafe_shutdowns);
22330d787e9bSWojciech Macek nvme_le128toh((void *)s->media_errors);
22340d787e9bSWojciech Macek nvme_le128toh((void *)s->num_error_info_log_entries);
22350d787e9bSWojciech Macek s->warning_temp_time = le32toh(s->warning_temp_time);
22360d787e9bSWojciech Macek s->error_temp_time = le32toh(s->error_temp_time);
22370d787e9bSWojciech Macek for (i = 0; i < 8; i++)
22380d787e9bSWojciech Macek s->temp_sensor[i] = le16toh(s->temp_sensor[i]);
223990dfa8f0SAlexander Motin s->tmt1tc = le32toh(s->tmt1tc);
22408dafbebdSAlexander Motin s->tmt2tc = le32toh(s->tmt2tc);
224190dfa8f0SAlexander Motin s->ttftmt1 = le32toh(s->ttftmt1);
224290dfa8f0SAlexander Motin s->ttftmt2 = le32toh(s->ttftmt2);
224352a83207SMichal Meloun #endif
22440d787e9bSWojciech Macek }
22450d787e9bSWojciech Macek
22460d787e9bSWojciech Macek static inline
nvme_ns_list_swapbytes(struct nvme_ns_list * s __unused)2247cf7c0629SMichal Meloun void nvme_ns_list_swapbytes(struct nvme_ns_list *s __unused)
2248f439e3a4SAlexander Motin {
224952a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
2250f439e3a4SAlexander Motin int i;
2251f439e3a4SAlexander Motin
2252f439e3a4SAlexander Motin for (i = 0; i < 1024; i++)
2253f439e3a4SAlexander Motin s->ns[i] = le32toh(s->ns[i]);
225452a83207SMichal Meloun #endif
2255f439e3a4SAlexander Motin }
2256f439e3a4SAlexander Motin
2257f439e3a4SAlexander Motin static inline
nvme_command_effects_page_swapbytes(struct nvme_command_effects_page * s __unused)2258b2e9e573SMichal Meloun void nvme_command_effects_page_swapbytes(
2259cf7c0629SMichal Meloun struct nvme_command_effects_page *s __unused)
22606c99d132SAlexander Motin {
226152a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
22626c99d132SAlexander Motin int i;
22636c99d132SAlexander Motin
22646c99d132SAlexander Motin for (i = 0; i < 256; i++)
22656c99d132SAlexander Motin s->acs[i] = le32toh(s->acs[i]);
22666c99d132SAlexander Motin for (i = 0; i < 256; i++)
22676c99d132SAlexander Motin s->iocs[i] = le32toh(s->iocs[i]);
226852a83207SMichal Meloun #endif
22696c99d132SAlexander Motin }
22706c99d132SAlexander Motin
22716c99d132SAlexander Motin static inline
nvme_res_notification_page_swapbytes(struct nvme_res_notification_page * s __unused)2272b2e9e573SMichal Meloun void nvme_res_notification_page_swapbytes(
2273cf7c0629SMichal Meloun struct nvme_res_notification_page *s __unused)
22746c99d132SAlexander Motin {
227552a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
22766c99d132SAlexander Motin s->log_page_count = le64toh(s->log_page_count);
22776c99d132SAlexander Motin s->nsid = le32toh(s->nsid);
227852a83207SMichal Meloun #endif
22796c99d132SAlexander Motin }
22806c99d132SAlexander Motin
22816c99d132SAlexander Motin static inline
nvme_sanitize_status_page_swapbytes(struct nvme_sanitize_status_page * s __unused)2282b2e9e573SMichal Meloun void nvme_sanitize_status_page_swapbytes(
2283cf7c0629SMichal Meloun struct nvme_sanitize_status_page *s __unused)
22846c99d132SAlexander Motin {
228552a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
22866c99d132SAlexander Motin s->sprog = le16toh(s->sprog);
22876c99d132SAlexander Motin s->sstat = le16toh(s->sstat);
22886c99d132SAlexander Motin s->scdw10 = le32toh(s->scdw10);
22896c99d132SAlexander Motin s->etfo = le32toh(s->etfo);
22906c99d132SAlexander Motin s->etfbe = le32toh(s->etfbe);
22916c99d132SAlexander Motin s->etfce = le32toh(s->etfce);
22926c99d132SAlexander Motin s->etfownd = le32toh(s->etfownd);
22936c99d132SAlexander Motin s->etfbewnd = le32toh(s->etfbewnd);
22946c99d132SAlexander Motin s->etfcewnd = le32toh(s->etfcewnd);
229552a83207SMichal Meloun #endif
22966c99d132SAlexander Motin }
22976c99d132SAlexander Motin
22986c99d132SAlexander Motin static inline
nvme_resv_status_swapbytes(struct nvme_resv_status * s __unused,size_t size __unused)2299cf7c0629SMichal Meloun void nvme_resv_status_swapbytes(struct nvme_resv_status *s __unused,
2300cf7c0629SMichal Meloun size_t size __unused)
230170d20ed3SAlexander Motin {
230252a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
23039a5acf36SDag-Erling Smørgrav size_t i, n;
230470d20ed3SAlexander Motin
230570d20ed3SAlexander Motin s->gen = le32toh(s->gen);
230670d20ed3SAlexander Motin n = (s->regctl[1] << 8) | s->regctl[0];
230770d20ed3SAlexander Motin n = MIN(n, (size - sizeof(s)) / sizeof(s->ctrlr[0]));
230870d20ed3SAlexander Motin for (i = 0; i < n; i++) {
230970d20ed3SAlexander Motin s->ctrlr[i].ctrlr_id = le16toh(s->ctrlr[i].ctrlr_id);
231070d20ed3SAlexander Motin s->ctrlr[i].hostid = le64toh(s->ctrlr[i].hostid);
231170d20ed3SAlexander Motin s->ctrlr[i].rkey = le64toh(s->ctrlr[i].rkey);
231270d20ed3SAlexander Motin }
231352a83207SMichal Meloun #endif
231470d20ed3SAlexander Motin }
231570d20ed3SAlexander Motin
231670d20ed3SAlexander Motin static inline
nvme_resv_status_ext_swapbytes(struct nvme_resv_status_ext * s __unused,size_t size __unused)2317cf7c0629SMichal Meloun void nvme_resv_status_ext_swapbytes(struct nvme_resv_status_ext *s __unused,
2318cf7c0629SMichal Meloun size_t size __unused)
231970d20ed3SAlexander Motin {
232052a83207SMichal Meloun #if _BYTE_ORDER != _LITTLE_ENDIAN
23219a5acf36SDag-Erling Smørgrav size_t i, n;
232270d20ed3SAlexander Motin
232370d20ed3SAlexander Motin s->gen = le32toh(s->gen);
232470d20ed3SAlexander Motin n = (s->regctl[1] << 8) | s->regctl[0];
232570d20ed3SAlexander Motin n = MIN(n, (size - sizeof(s)) / sizeof(s->ctrlr[0]));
232670d20ed3SAlexander Motin for (i = 0; i < n; i++) {
232770d20ed3SAlexander Motin s->ctrlr[i].ctrlr_id = le16toh(s->ctrlr[i].ctrlr_id);
232870d20ed3SAlexander Motin s->ctrlr[i].rkey = le64toh(s->ctrlr[i].rkey);
232970d20ed3SAlexander Motin nvme_le128toh((void *)s->ctrlr[i].hostid);
233070d20ed3SAlexander Motin }
233152a83207SMichal Meloun #endif
233270d20ed3SAlexander Motin }
233370d20ed3SAlexander Motin
233467334019SChuck Tuffli static inline void
nvme_device_self_test_swapbytes(struct nvme_device_self_test_page * s __unused)233567334019SChuck Tuffli nvme_device_self_test_swapbytes(struct nvme_device_self_test_page *s __unused)
233667334019SChuck Tuffli {
233767334019SChuck Tuffli #if _BYTE_ORDER != _LITTLE_ENDIAN
2338e83fdf8bSChuck Tuffli uint8_t *tmp;
2339e83fdf8bSChuck Tuffli uint32_t r, i;
2340e83fdf8bSChuck Tuffli uint8_t b;
234167334019SChuck Tuffli
234267334019SChuck Tuffli for (r = 0; r < 20; r++) {
234367334019SChuck Tuffli s->result[r].poh = le64toh(s->result[r].poh);
234467334019SChuck Tuffli s->result[r].nsid = le32toh(s->result[r].nsid);
234567334019SChuck Tuffli /* Unaligned 64-bit loads fail on some architectures */
2346e83fdf8bSChuck Tuffli tmp = s->result[r].failing_lba;
2347e83fdf8bSChuck Tuffli for (i = 0; i < 4; i++) {
2348e83fdf8bSChuck Tuffli b = tmp[i];
2349e83fdf8bSChuck Tuffli tmp[i] = tmp[7-i];
2350e83fdf8bSChuck Tuffli tmp[7-i] = b;
2351e83fdf8bSChuck Tuffli }
235267334019SChuck Tuffli }
235367334019SChuck Tuffli #endif
235467334019SChuck Tuffli }
235588ecf154SJohn Baldwin
235688ecf154SJohn Baldwin static inline void
nvme_discovery_log_entry_swapbytes(struct nvme_discovery_log_entry * s __unused)235788ecf154SJohn Baldwin nvme_discovery_log_entry_swapbytes(struct nvme_discovery_log_entry *s __unused)
235888ecf154SJohn Baldwin {
235988ecf154SJohn Baldwin #if _BYTE_ORDER != _LITTLE_ENDIAN
236088ecf154SJohn Baldwin s->portid = le16toh(s->portid);
236188ecf154SJohn Baldwin s->cntlid = le16toh(s->cntlid);
236288ecf154SJohn Baldwin s->aqsz = le16toh(s->aqsz);
236388ecf154SJohn Baldwin if (s->trtype == 0x01 /* RDMA */) {
236488ecf154SJohn Baldwin s->tsas.rdma.rdma_pkey = le16toh(s->tsas.rdma.rdma_pkey);
236588ecf154SJohn Baldwin }
236688ecf154SJohn Baldwin #endif
236788ecf154SJohn Baldwin }
236888ecf154SJohn Baldwin
236988ecf154SJohn Baldwin static inline void
nvme_discovery_log_swapbytes(struct nvme_discovery_log * s __unused)237088ecf154SJohn Baldwin nvme_discovery_log_swapbytes(struct nvme_discovery_log *s __unused)
237188ecf154SJohn Baldwin {
237288ecf154SJohn Baldwin #if _BYTE_ORDER != _LITTLE_ENDIAN
237388ecf154SJohn Baldwin s->genctr = le64toh(s->genctr);
237488ecf154SJohn Baldwin s->numrec = le64toh(s->numrec);
237588ecf154SJohn Baldwin s->recfmt = le16toh(s->recfmt);
237688ecf154SJohn Baldwin #endif
237788ecf154SJohn Baldwin }
2378bb0ec6b3SJim Harris #endif /* __NVME_H__ */
2379