xref: /freebsd/sys/dev/nvme/nvme.h (revision 7b3ee39e73af36f49f471f7900baeb98ac3504d0)
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