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