xref: /illumos-gate/usr/src/uts/common/sys/nvme/discovery.h (revision 533affcbc7fc4d0c8132976ea454aaa715fe2307)
1*533affcbSRobert Mustacchi /*
2*533affcbSRobert Mustacchi  * This file and its contents are supplied under the terms of the
3*533affcbSRobert Mustacchi  * Common Development and Distribution License ("CDDL"), version 1.0.
4*533affcbSRobert Mustacchi  * You may only use this file in accordance with the terms of version
5*533affcbSRobert Mustacchi  * 1.0 of the CDDL.
6*533affcbSRobert Mustacchi  *
7*533affcbSRobert Mustacchi  * A full copy of the text of the CDDL should have accompanied this
8*533affcbSRobert Mustacchi  * source.  A copy of the CDDL is also available via the Internet at
9*533affcbSRobert Mustacchi  * http://www.illumos.org/license/CDDL.
10*533affcbSRobert Mustacchi  */
11*533affcbSRobert Mustacchi 
12*533affcbSRobert Mustacchi /*
13*533affcbSRobert Mustacchi  * Copyright 2024 Oxide Computer Company
14*533affcbSRobert Mustacchi  */
15*533affcbSRobert Mustacchi 
16*533affcbSRobert Mustacchi #ifndef _SYS_NVME_DISCOVERY_H
17*533affcbSRobert Mustacchi #define	_SYS_NVME_DISCOVERY_H
18*533affcbSRobert Mustacchi 
19*533affcbSRobert Mustacchi /*
20*533affcbSRobert Mustacchi  * This defines common types that are used for discovering features of NVMe
21*533affcbSRobert Mustacchi  * devices. The primary way for users to consume these types is through the
22*533affcbSRobert Mustacchi  * libnvme discovery APIs.
23*533affcbSRobert Mustacchi  */
24*533affcbSRobert Mustacchi 
25*533affcbSRobert Mustacchi #ifdef __cplusplus
26*533affcbSRobert Mustacchi extern "C" {
27*533affcbSRobert Mustacchi #endif
28*533affcbSRobert Mustacchi 
29*533affcbSRobert Mustacchi typedef enum {
30*533affcbSRobert Mustacchi 	NVME_LOG_ID_MANDATORY,
31*533affcbSRobert Mustacchi 	NVME_LOG_ID_OPTIONAL,
32*533affcbSRobert Mustacchi 	NVME_LOG_ID_VENDOR_SPECIFIC
33*533affcbSRobert Mustacchi } nvme_log_disc_kind_t;
34*533affcbSRobert Mustacchi 
35*533affcbSRobert Mustacchi /*
36*533affcbSRobert Mustacchi  * Different logs cover different aspects of a device. These are listed below
37*533affcbSRobert Mustacchi  * referring to the NVMe controller, the NVM subsystem itself, and then
38*533affcbSRobert Mustacchi  * particular namespaces. NVMe 2.x adds the notion of a domain. From a
39*533affcbSRobert Mustacchi  * specification perspective, the NVM subsystem is instead sometimes referred to
40*533affcbSRobert Mustacchi  * as a domain. A controller can only access a single domain so while the 2.x
41*533affcbSRobert Mustacchi  * specifications suggest the scope is slightly different for the NVM subsystem
42*533affcbSRobert Mustacchi  * below, they're basically the same for our purposes.
43*533affcbSRobert Mustacchi  */
44*533affcbSRobert Mustacchi typedef enum {
45*533affcbSRobert Mustacchi 	NVME_LOG_SCOPE_CTRL	= 1 << 0,
46*533affcbSRobert Mustacchi 	NVME_LOG_SCOPE_NVM	= 1 << 1,
47*533affcbSRobert Mustacchi 	NVME_LOG_SCOPE_NS	= 1 << 2
48*533affcbSRobert Mustacchi } nvme_log_disc_scope_t;
49*533affcbSRobert Mustacchi 
50*533affcbSRobert Mustacchi typedef enum {
51*533affcbSRobert Mustacchi 	/*
52*533affcbSRobert Mustacchi 	 * This indicates that the implementation information is based on
53*533affcbSRobert Mustacchi 	 * knowledge from a base spec.
54*533affcbSRobert Mustacchi 	 */
55*533affcbSRobert Mustacchi 	NVME_LOG_DISC_S_SPEC	= 1 << 0,
56*533affcbSRobert Mustacchi 	/*
57*533affcbSRobert Mustacchi 	 * This indicates that the knowledge is from the identify controller
58*533affcbSRobert Mustacchi 	 * data structure.
59*533affcbSRobert Mustacchi 	 */
60*533affcbSRobert Mustacchi 	NVME_LOG_DISC_S_ID_CTRL	= 1 << 1,
61*533affcbSRobert Mustacchi 	/*
62*533affcbSRobert Mustacchi 	 * This indicates that we have used our internal information database
63*533affcbSRobert Mustacchi 	 * about devices from a vendor's datasheets to determine that something
64*533affcbSRobert Mustacchi 	 * is supported.
65*533affcbSRobert Mustacchi 	 */
66*533affcbSRobert Mustacchi 	NVME_LOG_DISC_S_DB	= 1 << 2,
67*533affcbSRobert Mustacchi 	/*
68*533affcbSRobert Mustacchi 	 * This indicates that we have used a command (whether vendor-specific
69*533affcbSRobert Mustacchi 	 * or the NVMe 2.x Supported Log Pages) to get additional information
70*533affcbSRobert Mustacchi 	 * about this.
71*533affcbSRobert Mustacchi 	 */
72*533affcbSRobert Mustacchi 	NVME_LOG_DISC_S_CMD	= 1 << 3
73*533affcbSRobert Mustacchi } nvme_log_disc_source_t;
74*533affcbSRobert Mustacchi 
75*533affcbSRobert Mustacchi typedef enum {
76*533affcbSRobert Mustacchi 	/*
77*533affcbSRobert Mustacchi 	 * These next three flags indicate that the log page requires additional
78*533affcbSRobert Mustacchi 	 * information for it to complete successfully. These are specifically
79*533affcbSRobert Mustacchi 	 * the log specific parameter or a log specific indicator (e.g. an
80*533affcbSRobert Mustacchi 	 * endurance group, NVM set, domain, etc.). RAE was introduced in NVMe
81*533affcbSRobert Mustacchi 	 * 1.3 and applied to logs that already existed. It will not be possible
82*533affcbSRobert Mustacchi 	 * to set RAE on a log request that operates on a controller prior to
83*533affcbSRobert Mustacchi 	 * NVMe 1.3.
84*533affcbSRobert Mustacchi 	 */
85*533affcbSRobert Mustacchi 	NVME_LOG_DISC_F_NEED_LSP	= 1 << 0,
86*533affcbSRobert Mustacchi 	NVME_LOG_DISC_F_NEED_LSI	= 1 << 1,
87*533affcbSRobert Mustacchi 	NVME_LOG_DISC_F_NEED_RAE	= 1 << 2,
88*533affcbSRobert Mustacchi 	/*
89*533affcbSRobert Mustacchi 	 * Log pages whose only scope is a namespace are required to specify a
90*533affcbSRobert Mustacchi 	 * namespace. Otherwise, when the scope includes a controller or NVM
91*533affcbSRobert Mustacchi 	 * subsystem then it is assumed that the default is to target the
92*533affcbSRobert Mustacchi 	 * controller (e.g.  the health log page).
93*533affcbSRobert Mustacchi 	 */
94*533affcbSRobert Mustacchi 	NVME_LOG_DISC_F_NEED_NSID	= 1 << 3
95*533affcbSRobert Mustacchi } nvme_log_disc_fields_t;
96*533affcbSRobert Mustacchi 
97*533affcbSRobert Mustacchi 
98*533affcbSRobert Mustacchi typedef enum {
99*533affcbSRobert Mustacchi 	NVME_FEAT_SCOPE_CTRL	= 1 << 0,
100*533affcbSRobert Mustacchi 	NVME_FEAT_SCOPE_NS	= 1 << 1
101*533affcbSRobert Mustacchi } nvme_feat_scope_t;
102*533affcbSRobert Mustacchi 
103*533affcbSRobert Mustacchi typedef enum {
104*533affcbSRobert Mustacchi 	/*
105*533affcbSRobert Mustacchi 	 * Indicates that this feature requires an argument to select some part
106*533affcbSRobert Mustacchi 	 * of the feature in cdw11.
107*533affcbSRobert Mustacchi 	 */
108*533affcbSRobert Mustacchi 	NVME_GET_FEAT_F_CDW11	= 1 << 0,
109*533affcbSRobert Mustacchi 	/*
110*533affcbSRobert Mustacchi 	 * Indicates that this feature will output data to a specific buffer and
111*533affcbSRobert Mustacchi 	 * therefore a data argument is required for this feature.
112*533affcbSRobert Mustacchi 	 */
113*533affcbSRobert Mustacchi 	NVME_GET_FEAT_F_DATA	= 1 << 1,
114*533affcbSRobert Mustacchi 	/*
115*533affcbSRobert Mustacchi 	 * Indicates that this feature requires a namespace ID to be specified
116*533affcbSRobert Mustacchi 	 * when getting this feature. In general, while one can usually set a
117*533affcbSRobert Mustacchi 	 * feature to target the broadcast namespace, the same is not true of
118*533affcbSRobert Mustacchi 	 * getting a feature.
119*533affcbSRobert Mustacchi 	 */
120*533affcbSRobert Mustacchi 	NVME_GET_FEAT_F_NSID	= 1 << 2,
121*533affcbSRobert Mustacchi } nvme_get_feat_fields_t;
122*533affcbSRobert Mustacchi 
123*533affcbSRobert Mustacchi typedef enum {
124*533affcbSRobert Mustacchi 	/*
125*533affcbSRobert Mustacchi 	 * These indicate that the feature requires fields set in the various
126*533affcbSRobert Mustacchi 	 * control words to set the feature.
127*533affcbSRobert Mustacchi 	 */
128*533affcbSRobert Mustacchi 	NVME_SET_FEAT_F_CDW11	= 1 << 0,
129*533affcbSRobert Mustacchi 	NVME_SET_FEAT_F_CDW12	= 1 << 1,
130*533affcbSRobert Mustacchi 	NVME_SET_FEAT_F_CDW13	= 1 << 2,
131*533affcbSRobert Mustacchi 	NVME_SET_FEAT_F_CDW14	= 1 << 3,
132*533affcbSRobert Mustacchi 	NVME_SET_FEAT_F_CDW15	= 1 << 4,
133*533affcbSRobert Mustacchi 	/*
134*533affcbSRobert Mustacchi 	 * Indicates that there is a data payload component to this feature that
135*533affcbSRobert Mustacchi 	 * must be set.
136*533affcbSRobert Mustacchi 	 */
137*533affcbSRobert Mustacchi 	NVME_SET_FEAT_F_DATA	= 1 << 5,
138*533affcbSRobert Mustacchi 	/*
139*533affcbSRobert Mustacchi 	 * Indicates that this feature requires a namespace ID. Broadcast IDs
140*533affcbSRobert Mustacchi 	 * are more often allowed than with getting a feature, but it still
141*533affcbSRobert Mustacchi 	 * depends.
142*533affcbSRobert Mustacchi 	 */
143*533affcbSRobert Mustacchi 	NVME_SET_FEAT_F_NSID	= 1 << 6
144*533affcbSRobert Mustacchi } nvme_set_feat_fields_t;
145*533affcbSRobert Mustacchi 
146*533affcbSRobert Mustacchi typedef enum {
147*533affcbSRobert Mustacchi 	/*
148*533affcbSRobert Mustacchi 	 * Indicates that getting the feature outputs data in cdw0 for
149*533affcbSRobert Mustacchi 	 * consumption. This is the most common form of data output for getting
150*533affcbSRobert Mustacchi 	 * features. Setting features usually doesn't output data in cdw0;
151*533affcbSRobert Mustacchi 	 * however, a few are defined to.
152*533affcbSRobert Mustacchi 	 */
153*533affcbSRobert Mustacchi 	NVME_FEAT_OUTPUT_CDW0	= 1 << 0,
154*533affcbSRobert Mustacchi 	/*
155*533affcbSRobert Mustacchi 	 * Indicates that data is output in the data buffer that was passed in.
156*533affcbSRobert Mustacchi 	 * This is only ever used for get features.
157*533affcbSRobert Mustacchi 	 */
158*533affcbSRobert Mustacchi 	NVME_FEAT_OUTPUT_DATA	= 1 << 1
159*533affcbSRobert Mustacchi } nvme_feat_output_t;
160*533affcbSRobert Mustacchi 
161*533affcbSRobert Mustacchi typedef enum {
162*533affcbSRobert Mustacchi 	/*
163*533affcbSRobert Mustacchi 	 * Indicates that when getting or setting this feature that requires a
164*533affcbSRobert Mustacchi 	 * namespace ID, the broadcast namespace is allowed.
165*533affcbSRobert Mustacchi 	 */
166*533affcbSRobert Mustacchi 	NVME_FEAT_F_GET_BCAST_NSID	= 1 << 0,
167*533affcbSRobert Mustacchi 	NVME_FEAT_F_SET_BCAST_NSID	= 1 << 1
168*533affcbSRobert Mustacchi } nvme_feat_flags_t;
169*533affcbSRobert Mustacchi 
170*533affcbSRobert Mustacchi typedef enum {
171*533affcbSRobert Mustacchi 	NVME_FEAT_MANDATORY	= 0,
172*533affcbSRobert Mustacchi 	NVME_FEAT_OPTIONAL,
173*533affcbSRobert Mustacchi 	NVME_FEAT_VENDOR_SPECIFIC
174*533affcbSRobert Mustacchi } nvme_feat_kind_t;
175*533affcbSRobert Mustacchi 
176*533affcbSRobert Mustacchi /*
177*533affcbSRobert Mustacchi  * This enumeration indicates whether or not a given feature is specific to a
178*533affcbSRobert Mustacchi  * command set, and if so what one. The default is that most features are
179*533affcbSRobert Mustacchi  * present for all command sets, which uses the NVME_FEAT_CSI_NONE value.
180*533affcbSRobert Mustacchi  * Otherwise, it uses a bit-field to indicate what it is present in.
181*533affcbSRobert Mustacchi  */
182*533affcbSRobert Mustacchi typedef enum {
183*533affcbSRobert Mustacchi 	NVME_FEAT_CSI_NONE	= 0,
184*533affcbSRobert Mustacchi 	NVME_FEAT_CSI_NVM	= 1 << 0,
185*533affcbSRobert Mustacchi } nvme_feat_csi_t;
186*533affcbSRobert Mustacchi 
187*533affcbSRobert Mustacchi /*
188*533affcbSRobert Mustacchi  * Prior to NVMe 2.x, there was no standard way to determine if a given log page
189*533affcbSRobert Mustacchi  * was actually implemented or not. While several features had bits in the
190*533affcbSRobert Mustacchi  * identify controller namespace, some (e.g. LBA Range Type) are optional,
191*533affcbSRobert Mustacchi  * command-set specific, and have no such way of knowing if they're supported
192*533affcbSRobert Mustacchi  * short of saying so. If we cannot determine this from the controller's
193*533affcbSRobert Mustacchi  * version, type, and identify controller information, then we will indicate
194*533affcbSRobert Mustacchi  * that we don't know. When we have full support for leveraging the NVMe 2.x
195*533affcbSRobert Mustacchi  * Feature Identifiers Supported and Effects log pages and someone is
196*533affcbSRobert Mustacchi  * interrogating an NVMe 2.x controller, then ideally one should not see
197*533affcbSRobert Mustacchi  * unknown.
198*533affcbSRobert Mustacchi  */
199*533affcbSRobert Mustacchi typedef enum {
200*533affcbSRobert Mustacchi 	NVME_FEAT_IMPL_UNKNOWN = 0,
201*533affcbSRobert Mustacchi 	NVME_FEAT_IMPL_UNSUPPORTED,
202*533affcbSRobert Mustacchi 	NVME_FEAT_IMPL_SUPPORTED
203*533affcbSRobert Mustacchi } nvme_feat_impl_t;
204*533affcbSRobert Mustacchi 
205*533affcbSRobert Mustacchi #ifdef __cplusplus
206*533affcbSRobert Mustacchi }
207*533affcbSRobert Mustacchi #endif
208*533affcbSRobert Mustacchi 
209*533affcbSRobert Mustacchi #endif /* _SYS_NVME_DISCOVERY_H */
210