13d9b1a2aSHans Rosenfeld /* 23d9b1a2aSHans Rosenfeld * This file and its contents are supplied under the terms of the 33d9b1a2aSHans Rosenfeld * Common Development and Distribution License ("CDDL"), version 1.0. 43d9b1a2aSHans Rosenfeld * You may only use this file in accordance with the terms of version 53d9b1a2aSHans Rosenfeld * 1.0 of the CDDL. 63d9b1a2aSHans Rosenfeld * 73d9b1a2aSHans Rosenfeld * A full copy of the text of the CDDL should have accompanied this 83d9b1a2aSHans Rosenfeld * source. A copy of the CDDL is also available via the Internet at 93d9b1a2aSHans Rosenfeld * http://www.illumos.org/license/CDDL. 103d9b1a2aSHans Rosenfeld */ 113d9b1a2aSHans Rosenfeld 123d9b1a2aSHans Rosenfeld /* 133d9b1a2aSHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc. 143c6ffbabSRob Johnston * Copyright 2020 Joyent, Inc. 15cf840871SPaul Winder * Copyright 2019 Western Digital Corporation 16533affcbSRobert Mustacchi * Copyright 2024 Oxide Computer Company 1704be5853SAndy Fiddaman * Copyright 2022 OmniOS Community Edition (OmniOSce) Association. 183d9b1a2aSHans Rosenfeld */ 193d9b1a2aSHans Rosenfeld 203d9b1a2aSHans Rosenfeld #ifndef _SYS_NVME_H 213d9b1a2aSHans Rosenfeld #define _SYS_NVME_H 223d9b1a2aSHans Rosenfeld 233d9b1a2aSHans Rosenfeld #include <sys/types.h> 24153f3212SHans Rosenfeld #include <sys/debug.h> 25*046911ebSRobert Mustacchi #include <sys/stddef.h> 263d9b1a2aSHans Rosenfeld 273d9b1a2aSHans Rosenfeld #ifdef _KERNEL 283d9b1a2aSHans Rosenfeld #include <sys/types32.h> 293d9b1a2aSHans Rosenfeld #else 30153f3212SHans Rosenfeld #include <sys/uuid.h> 313d9b1a2aSHans Rosenfeld #include <stdint.h> 323d9b1a2aSHans Rosenfeld #endif 333d9b1a2aSHans Rosenfeld 343d9b1a2aSHans Rosenfeld /* 35bbf21555SRichard Lowe * Declarations used for communication between nvmeadm(8) and nvme(4D) 363d9b1a2aSHans Rosenfeld */ 373d9b1a2aSHans Rosenfeld 383d9b1a2aSHans Rosenfeld #ifdef __cplusplus 393d9b1a2aSHans Rosenfeld extern "C" { 403d9b1a2aSHans Rosenfeld #endif 413d9b1a2aSHans Rosenfeld 423d9b1a2aSHans Rosenfeld /* 433d9b1a2aSHans Rosenfeld * NVMe ioctl definitions 443d9b1a2aSHans Rosenfeld */ 453d9b1a2aSHans Rosenfeld 463d9b1a2aSHans Rosenfeld #define NVME_IOC (('N' << 24) | ('V' << 16) | ('M' << 8)) 47533affcbSRobert Mustacchi #define NVME_IOC_CTRL_INFO (NVME_IOC | 0) 48153f3212SHans Rosenfeld #define NVME_IOC_IDENTIFY (NVME_IOC | 1) 49533affcbSRobert Mustacchi #define NVME_IOC_GET_LOGPAGE (NVME_IOC | 2) 50533affcbSRobert Mustacchi #define NVME_IOC_GET_FEATURE (NVME_IOC | 3) 51533affcbSRobert Mustacchi #define NVME_IOC_FORMAT (NVME_IOC | 4) 52533affcbSRobert Mustacchi #define NVME_IOC_DETACH (NVME_IOC | 5) 53533affcbSRobert Mustacchi #define NVME_IOC_ATTACH (NVME_IOC | 6) 54533affcbSRobert Mustacchi #define NVME_IOC_FIRMWARE_DOWNLOAD (NVME_IOC | 7) 55533affcbSRobert Mustacchi #define NVME_IOC_FIRMWARE_COMMIT (NVME_IOC | 8) 56533affcbSRobert Mustacchi #define NVME_IOC_PASSTHRU (NVME_IOC | 9) 57533affcbSRobert Mustacchi #define NVME_IOC_NS_INFO (NVME_IOC | 10) 58533affcbSRobert Mustacchi #define NVME_IOC_LOCK (NVME_IOC | 11) 59533affcbSRobert Mustacchi #define NVME_IOC_UNLOCK (NVME_IOC | 12) 60744642a2SRobert Mustacchi #define NVME_IOC_MAX NVME_IOC_NS_INFO 613d9b1a2aSHans Rosenfeld 623d9b1a2aSHans Rosenfeld #define IS_NVME_IOC(x) ((x) > NVME_IOC && (x) <= NVME_IOC_MAX) 633d9b1a2aSHans Rosenfeld #define NVME_IOC_CMD(x) ((x) & 0xff) 643d9b1a2aSHans Rosenfeld 65533affcbSRobert Mustacchi /* 66533affcbSRobert Mustacchi * This represents the set of all possible errors that can be returned from an 67533affcbSRobert Mustacchi * ioctl. Our general rule of thumb is that we only will use an errno value to 68533affcbSRobert Mustacchi * indicate that certain processing failed: a lack of privileges, bad minor, or 69533affcbSRobert Mustacchi * failure to copy in and out the initial ioctl structure. However, if we get 70533affcbSRobert Mustacchi * far enough that there is any other failure (including a failure to copy in 71533affcbSRobert Mustacchi * and out nested data such as the identify command payload) then we will issue 72533affcbSRobert Mustacchi * an error here. Put differently, our basic promise is that there should be a 73533affcbSRobert Mustacchi * single straightforward meaning for any errno returned and instead all the 74533affcbSRobert Mustacchi * nuance is here. Our goal is that no one should guess what of two dozen things 75533affcbSRobert Mustacchi * an EINVAL might have referred to. 76533affcbSRobert Mustacchi * 77533affcbSRobert Mustacchi * When we are dealing with field parameters, there are three general classes of 78533affcbSRobert Mustacchi * errors that we define that are common across all request structures: 79533affcbSRobert Mustacchi * 80533affcbSRobert Mustacchi * <REQ>_<FIELD>_RANGE RANGE class errors indicate that the value 81533affcbSRobert Mustacchi * passed in is outside the range that the device 82533affcbSRobert Mustacchi * supports. The range may vary based on the 83533affcbSRobert Mustacchi * specification. This is used both for issues like 84533affcbSRobert Mustacchi * bad alignment in a value (e.g. not 4-byte 85533affcbSRobert Mustacchi * aligned) or a value that is larger than the 86533affcbSRobert Mustacchi * maximum possible size. Because the namespace ID 87533affcbSRobert Mustacchi * is shared in every request in the controller and 88533affcbSRobert Mustacchi * is part of our standard ioctl handling, we use a 89533affcbSRobert Mustacchi * single set of errors for that. 90533affcbSRobert Mustacchi * 91533affcbSRobert Mustacchi * <REQ>_<FIELD>_UNSUP This indicates that the controller cannot 92533affcbSRobert Mustacchi * support any value in the given field. This is 93533affcbSRobert Mustacchi * either because the field was introduced in an 94533affcbSRobert Mustacchi * NVMe specification later than the controller 95533affcbSRobert Mustacchi * supports or because there is an explicit feature 96533affcbSRobert Mustacchi * bit that indicates whether or not this field is 97533affcbSRobert Mustacchi * valid. Entries here may or may not have a 98533affcbSRobert Mustacchi * namespace unsupported entry due to the fact that 99533affcbSRobert Mustacchi * this is command specific. 100533affcbSRobert Mustacchi * 101533affcbSRobert Mustacchi * <REQ>_<FIELD>_UNUSE This class is perhaps the weirdest. This 102533affcbSRobert Mustacchi * represents a case where a given field cannot be 103533affcbSRobert Mustacchi * set because it is not used based on the 104533affcbSRobert Mustacchi * specifics of the request. For example, if you're 105533affcbSRobert Mustacchi * getting the health log page, you may not set the 106533affcbSRobert Mustacchi * LSP or LSI for that log page, even if you have 107533affcbSRobert Mustacchi * an NVMe 1.4 controller that supports both fields 108533affcbSRobert Mustacchi * because they have no meaning. A similar example 109533affcbSRobert Mustacchi * would be setting a controller ID when it has no 110533affcbSRobert Mustacchi * meaning in a particular identify request. 111533affcbSRobert Mustacchi * 112533affcbSRobert Mustacchi * While every field will have a RANGE class error, some fields will not have an 113533affcbSRobert Mustacchi * UNSUP or UNUSE class error depending on the specifics. A field that has 114533affcbSRobert Mustacchi * always been present since NVMe 1.0 and is always valid, such as say the log 115533affcbSRobert Mustacchi * page ID field for a get log page request or the length of a firmware download 116533affcbSRobert Mustacchi * request, currently are always valid. It is possible that future revisions to 117533affcbSRobert Mustacchi * the specification or our logic may change this. 118533affcbSRobert Mustacchi */ 119533affcbSRobert Mustacchi typedef enum { 120533affcbSRobert Mustacchi /* 121533affcbSRobert Mustacchi * Indicates that the command actually completed successfully. 122533affcbSRobert Mustacchi */ 123533affcbSRobert Mustacchi NVME_IOCTL_E_OK = 0, 124533affcbSRobert Mustacchi /* 125533affcbSRobert Mustacchi * Indicates that the controller failed the command and the controller 126533affcbSRobert Mustacchi * specific (SC/SCT) are available. For all other errors, those fields 127533affcbSRobert Mustacchi * are reserved. 128533affcbSRobert Mustacchi */ 129533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_ERROR, 130533affcbSRobert Mustacchi /* 131533affcbSRobert Mustacchi * Indicates that the controller is considered "dead" by the system and 132533affcbSRobert Mustacchi * therefore is unusable. Separately, the controller may have been 133533affcbSRobert Mustacchi * removed from the system due to hotplug or related. In that case, the 134533affcbSRobert Mustacchi * gone variant is used to distinguish this. 135533affcbSRobert Mustacchi */ 136533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_DEAD, 137533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_GONE, 138533affcbSRobert Mustacchi /* 139533affcbSRobert Mustacchi * Indicates that a bad namespace was requested. This would generally 140533affcbSRobert Mustacchi * happen when referring to a namespace that is outside of controller's 141533affcbSRobert Mustacchi * range. 142533affcbSRobert Mustacchi */ 143533affcbSRobert Mustacchi NVME_IOCTL_E_NS_RANGE, 144533affcbSRobert Mustacchi /* 145533affcbSRobert Mustacchi * Indicates that a namespace is not usable in this context. 146533affcbSRobert Mustacchi */ 147533affcbSRobert Mustacchi NVME_IOCTL_E_NS_UNUSE, 148533affcbSRobert Mustacchi /* 149533affcbSRobert Mustacchi * Indicates that the requested namespace could not be used because we 150533affcbSRobert Mustacchi * are operating on a namespace minor and asked to operate on a 151533affcbSRobert Mustacchi * different namespace. 152533affcbSRobert Mustacchi */ 153533affcbSRobert Mustacchi NVME_IOCTL_E_MINOR_WRONG_NS, 154533affcbSRobert Mustacchi /* 155533affcbSRobert Mustacchi * Indicates that the requested ioctl can only operate on the controller 156533affcbSRobert Mustacchi * minor and we were on a namespace minor. This is not used for when a 157533affcbSRobert Mustacchi * namespace is incorrectly requested otherwise. 158533affcbSRobert Mustacchi */ 159533affcbSRobert Mustacchi NVME_IOCTL_E_NOT_CTRL, 160533affcbSRobert Mustacchi /* 161533affcbSRobert Mustacchi * Indicates that we were asked to operate on the broadcast namespace 162533affcbSRobert Mustacchi * either because it was specified or that was how the request was 163533affcbSRobert Mustacchi * transformed and the broadcast namespace is not supported for this 164533affcbSRobert Mustacchi * operation. 165533affcbSRobert Mustacchi */ 166533affcbSRobert Mustacchi NVME_IOCTL_E_NO_BCAST_NS, 167533affcbSRobert Mustacchi /* 168533affcbSRobert Mustacchi * Indicates that the operation failed because the operation requires a 169533affcbSRobert Mustacchi * controller or namespace write lock and the caller did not have it. 170533affcbSRobert Mustacchi */ 171533affcbSRobert Mustacchi NVME_IOCTL_E_NEED_CTRL_WRLOCK, 172533affcbSRobert Mustacchi NVME_IOCTL_E_NEED_NS_WRLOCK, 173533affcbSRobert Mustacchi /* 174533affcbSRobert Mustacchi * Indicates that the operation could not proceed because someone else 175533affcbSRobert Mustacchi * has exclusive access currently to the controller or namespace and 176533affcbSRobert Mustacchi * therefore this request (which does not require exclusive access) 177533affcbSRobert Mustacchi * could not proceed. 178533affcbSRobert Mustacchi */ 179533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_LOCKED, 180533affcbSRobert Mustacchi NVME_IOCTL_E_NS_LOCKED, 181533affcbSRobert Mustacchi /* 182533affcbSRobert Mustacchi * Indicates that a standard log page was requested that the kernel 183533affcbSRobert Mustacchi * doesn't know about. 184533affcbSRobert Mustacchi */ 185533affcbSRobert Mustacchi NVME_IOCTL_E_UNKNOWN_LOG_PAGE, 186533affcbSRobert Mustacchi /* 187533affcbSRobert Mustacchi * Indicates that the controller does not support the requested log 188533affcbSRobert Mustacchi * page; however, the kernel knows about it. 189533affcbSRobert Mustacchi */ 190533affcbSRobert Mustacchi NVME_IOCTL_E_UNSUP_LOG_PAGE, 191533affcbSRobert Mustacchi /* 192533affcbSRobert Mustacchi * Indicates that the log page's scope requires operating on something 193533affcbSRobert Mustacchi * that isn't what was requested. For example, trying to request the 194533affcbSRobert Mustacchi * firmware information page on a namespace. 195533affcbSRobert Mustacchi */ 196533affcbSRobert Mustacchi NVME_IOCTL_E_BAD_LOG_SCOPE, 197533affcbSRobert Mustacchi /* 198533affcbSRobert Mustacchi * Log page fields with bad values. 199533affcbSRobert Mustacchi */ 200533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_CSI_RANGE, 201533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_LID_RANGE, 202533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_LSP_RANGE, 203533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_LSI_RANGE, 204533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_RAE_RANGE, 205533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_SIZE_RANGE, 206533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_OFFSET_RANGE, 207533affcbSRobert Mustacchi /* 208533affcbSRobert Mustacchi * Log page fields that may not be supported. 209533affcbSRobert Mustacchi */ 210533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_CSI_UNSUP, 211533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_LSP_UNSUP, 212533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_LSI_UNSUP, 213533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_RAE_UNSUP, 214533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_OFFSET_UNSUP, 215533affcbSRobert Mustacchi /* 216533affcbSRobert Mustacchi * Log page fields that may not be usable, depending on context. 217533affcbSRobert Mustacchi */ 218533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_LSP_UNUSE, 219533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_LSI_UNUSE, 220533affcbSRobert Mustacchi NVME_IOCTL_E_LOG_RAE_UNUSE, 221533affcbSRobert Mustacchi /* 222533affcbSRobert Mustacchi * Indicates that no DMA memory was available for a request. 223533affcbSRobert Mustacchi */ 224533affcbSRobert Mustacchi NVME_IOCTL_E_NO_DMA_MEM, 225533affcbSRobert Mustacchi /* 226533affcbSRobert Mustacchi * Indicates that there was no kernel memory avilable for the request. 227533affcbSRobert Mustacchi */ 228533affcbSRobert Mustacchi NVME_IOCTL_E_NO_KERN_MEM, 229533affcbSRobert Mustacchi /* 230533affcbSRobert Mustacchi * Indicates that an error occurred while trying to fill out the DMA PRP 231533affcbSRobert Mustacchi */ 232533affcbSRobert Mustacchi NVME_IOCTL_E_BAD_PRP, 233533affcbSRobert Mustacchi /* 234533affcbSRobert Mustacchi * Indicates that a pointer to user data to read from or write to was 235533affcbSRobert Mustacchi * not valid and generated a fault. Specifically this is for items that 236533affcbSRobert Mustacchi * an ioctl structure points to. 237533affcbSRobert Mustacchi */ 238533affcbSRobert Mustacchi NVME_IOCTL_E_BAD_USER_DATA, 239533affcbSRobert Mustacchi /* 240533affcbSRobert Mustacchi * Indicates that the kernel does not know about the requested identify 241533affcbSRobert Mustacchi * command. 242533affcbSRobert Mustacchi */ 243533affcbSRobert Mustacchi NVME_IOCTL_E_UNKNOWN_IDENTIFY, 244533affcbSRobert Mustacchi /* 245533affcbSRobert Mustacchi * Indicates that the controller does not support the requested identify 246533affcbSRobert Mustacchi * command. 247533affcbSRobert Mustacchi */ 248533affcbSRobert Mustacchi NVME_IOCTL_E_UNSUP_IDENTIFY, 249533affcbSRobert Mustacchi /* 250533affcbSRobert Mustacchi * The following errors indicate either a bad value for a given identify 251533affcbSRobert Mustacchi * argument. This would happen because the value is outside the 252533affcbSRobert Mustacchi * supported range. There is no CNS or below as those are the 253533affcbSRobert Mustacchi * higher-level errors right above this. 254533affcbSRobert Mustacchi */ 255533affcbSRobert Mustacchi NVME_IOCTL_E_IDENTIFY_CTRLID_RANGE, 256533affcbSRobert Mustacchi /* 257533affcbSRobert Mustacchi * Next, we have the unsupported and unusable pieces. The nsid was 258533affcbSRobert Mustacchi * supported starting in NVMe 1.0, therefore it is never unsupported. 259533affcbSRobert Mustacchi * However, the controller ID both requires controller support and is 260533affcbSRobert Mustacchi * not usable in several requests. 261533affcbSRobert Mustacchi */ 262533affcbSRobert Mustacchi NVME_IOCTL_E_IDENTIFY_CTRLID_UNSUP, 263533affcbSRobert Mustacchi NVME_IOCTL_E_IDENTIFY_CTRLID_UNUSE, 264533affcbSRobert Mustacchi /* 265533affcbSRobert Mustacchi * Indicates that the controller does not support the NVMe spec's 266533affcbSRobert Mustacchi * general vendor unique command format. 267533affcbSRobert Mustacchi */ 268533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_VUC_UNSUP, 269533affcbSRobert Mustacchi /* 270533affcbSRobert Mustacchi * The following indicate bad values for given NVMe vendor unique 271533affcbSRobert Mustacchi * command fields. All of the cdw1[2-5] fields are not part of this 272533affcbSRobert Mustacchi * because there is nothing that we can validate. 273533affcbSRobert Mustacchi */ 274533affcbSRobert Mustacchi NVME_IOCTL_E_VUC_TIMEOUT_RANGE, 275533affcbSRobert Mustacchi NVME_IOCTL_E_VUC_OPCODE_RANGE, 276533affcbSRobert Mustacchi NVME_IOCTL_E_VUC_FLAGS_RANGE, 277533affcbSRobert Mustacchi NVME_IOCTL_E_VUC_IMPACT_RANGE, 278533affcbSRobert Mustacchi NVME_IOCTL_E_VUC_NDT_RANGE, 279533affcbSRobert Mustacchi /* 280533affcbSRobert Mustacchi * These indicate that the VUC data and that the corresponding pair of 281533affcbSRobert Mustacchi * fields do not agree with each other. 282533affcbSRobert Mustacchi */ 283533affcbSRobert Mustacchi NVME_IOCTL_E_INCONSIST_VUC_FLAGS_NDT, 284533affcbSRobert Mustacchi NVME_IOCTL_E_INCONSIST_VUC_BUF_NDT, 285533affcbSRobert Mustacchi /* 286533affcbSRobert Mustacchi * Indicates that the operation in question did not succeed because 287533affcbSRobert Mustacchi * blkdev failed to detach. Most often this happens because the device 288533affcbSRobert Mustacchi * node is busy. Reasons the device node could be busy include that the 289533affcbSRobert Mustacchi * device is in a zpool, a file system is mounted, a process has the 290533affcbSRobert Mustacchi * block device open, etc. 291533affcbSRobert Mustacchi */ 292533affcbSRobert Mustacchi NVME_IOCTL_E_BLKDEV_DETACH, 293533affcbSRobert Mustacchi /* 294533affcbSRobert Mustacchi * Indicates that the operation in question failed because we were 295533affcbSRobert Mustacchi * unable to create and online a new blkdev child. 296533affcbSRobert Mustacchi */ 297533affcbSRobert Mustacchi NVME_IOCTL_E_BLKDEV_ATTACH, 298533affcbSRobert Mustacchi /* 299533affcbSRobert Mustacchi * Indicates that the namespace requested for an attach is not supported 300533affcbSRobert Mustacchi * by the system. This would happen due to properties of the namespace 301533affcbSRobert Mustacchi * itself (e.g. utilizing metadata sectors). 302533affcbSRobert Mustacchi */ 303533affcbSRobert Mustacchi NVME_IOCTL_E_UNSUP_ATTACH_NS, 304533affcbSRobert Mustacchi /* 305533affcbSRobert Mustacchi * Indicates that the format operation is not supported by the 306533affcbSRobert Mustacchi * controller at all. 307533affcbSRobert Mustacchi */ 308533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_FORMAT_UNSUP, 309533affcbSRobert Mustacchi /* 310533affcbSRobert Mustacchi * Indicates that the controller does not support the ability to perform 311533affcbSRobert Mustacchi * a cryptographic secure erase. 312533affcbSRobert Mustacchi */ 313533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_CRYPTO_SE_UNSUP, 314533affcbSRobert Mustacchi /* 315533affcbSRobert Mustacchi * Indicates that a format operation is targeting a namespace, but 316533affcbSRobert Mustacchi * cannot be performed because it does not support formatting an 317533affcbSRobert Mustacchi * individual namespace or performing a secure-erase of an individual 318533affcbSRobert Mustacchi * namespace respectively. 319533affcbSRobert Mustacchi */ 320533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_NS_FORMAT_UNSUP, 321533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_NS_SE_UNSUP, 322533affcbSRobert Mustacchi /* 323533affcbSRobert Mustacchi * The following indicate bad values for a format NVM request. 324533affcbSRobert Mustacchi */ 325533affcbSRobert Mustacchi NVME_IOCTL_E_FORMAT_LBAF_RANGE, 326533affcbSRobert Mustacchi NVME_IOCTL_E_FORMAT_SES_RANGE, 327533affcbSRobert Mustacchi /* 328533affcbSRobert Mustacchi * Indicates that the requested LBA format is not supported due to its 329533affcbSRobert Mustacchi * use of metadata. 330533affcbSRobert Mustacchi */ 331533affcbSRobert Mustacchi NVME_IOCTL_E_UNSUP_LBAF_META, 332533affcbSRobert Mustacchi /* 333533affcbSRobert Mustacchi * Indicates that the firmware commands are not supported by the 334533affcbSRobert Mustacchi * controller at all. 335533affcbSRobert Mustacchi */ 336533affcbSRobert Mustacchi NVME_IOCTL_E_CTRL_FW_UNSUP, 337533affcbSRobert Mustacchi /* 338533affcbSRobert Mustacchi * Indicates that the controller has reported a firmware update 339533affcbSRobert Mustacchi * granularity that exceeds the calculated / driver supported maximum 340533affcbSRobert Mustacchi * DMA transfer size. As such we cannot perform this operation. 341533affcbSRobert Mustacchi */ 342533affcbSRobert Mustacchi NVME_IOCTL_E_FW_LOAD_IMPOS_GRAN, 343533affcbSRobert Mustacchi /* 344533affcbSRobert Mustacchi * The following indicate bad values for a firmware load's length and 345533affcbSRobert Mustacchi * offset. 346533affcbSRobert Mustacchi */ 347533affcbSRobert Mustacchi NVME_IOCTL_E_FW_LOAD_LEN_RANGE, 348533affcbSRobert Mustacchi NVME_IOCTL_E_FW_LOAD_OFFSET_RANGE, 349533affcbSRobert Mustacchi /* 350533affcbSRobert Mustacchi * The following indicate bad values for a firmware commit's slot and 351533affcbSRobert Mustacchi * action. 352533affcbSRobert Mustacchi */ 353533affcbSRobert Mustacchi NVME_IOCTL_E_FW_COMMIT_SLOT_RANGE, 354533affcbSRobert Mustacchi NVME_IOCTL_E_FW_COMMIT_ACTION_RANGE, 355533affcbSRobert Mustacchi /* 356533affcbSRobert Mustacchi * Indicates that an explicit attempt was made to download an image into 357533affcbSRobert Mustacchi * a read-only slot. Note, some instances of this cannot be caught prior 358533affcbSRobert Mustacchi * to issuing a command to the controller (commit action 0b11 as it can 359533affcbSRobert Mustacchi * be used whether there is or isn't a staged image) and will result in 360533affcbSRobert Mustacchi * a controller error. 361533affcbSRobert Mustacchi */ 362533affcbSRobert Mustacchi NVME_IOCTL_E_RO_FW_SLOT, 363533affcbSRobert Mustacchi /* 364533affcbSRobert Mustacchi * Indicates that the kernel doesn't know about the NVMe feature in 365533affcbSRobert Mustacchi * question and therefore cannot proceed. 366533affcbSRobert Mustacchi */ 367533affcbSRobert Mustacchi NVME_IOCTL_E_UNKNOWN_FEATURE, 368533affcbSRobert Mustacchi /* 369533affcbSRobert Mustacchi * Indicates that while the system knows about the feature in question, 370533affcbSRobert Mustacchi * it is not supported by the controller. 371533affcbSRobert Mustacchi */ 372533affcbSRobert Mustacchi NVME_IOCTL_E_UNSUP_FEATURE, 373533affcbSRobert Mustacchi /* 374533affcbSRobert Mustacchi * The following errors indicate a bad value for a given get feature 375533affcbSRobert Mustacchi * field. This would happen because the value is outside the supported 376533affcbSRobert Mustacchi * range. 377533affcbSRobert Mustacchi */ 378533affcbSRobert Mustacchi NVME_IOCTL_E_GET_FEAT_SEL_RANGE, 379533affcbSRobert Mustacchi NVME_IOCTL_E_GET_FEAT_CDW11_RANGE, 380533affcbSRobert Mustacchi NVME_IOCTL_E_GET_FEAT_DATA_RANGE, 381533affcbSRobert Mustacchi /* 382533affcbSRobert Mustacchi * This set of errors indicate that the field is not supported. This can 383533affcbSRobert Mustacchi * happen because a given get feature command doesn't support setting 384533affcbSRobert Mustacchi * this value, the field isn't supported in this revision of the 385533affcbSRobert Mustacchi * controller, or similar issues. 386533affcbSRobert Mustacchi */ 387533affcbSRobert Mustacchi NVME_IOCTL_E_GET_FEAT_SEL_UNSUP, 388533affcbSRobert Mustacchi /* 389533affcbSRobert Mustacchi * Fields that may be circumstantially unusable. 390533affcbSRobert Mustacchi */ 391533affcbSRobert Mustacchi NVME_IOCTL_E_GET_FEAT_CDW11_UNUSE, 392533affcbSRobert Mustacchi NVME_IOCTL_E_GET_FEAT_DATA_UNUSE, 393533affcbSRobert Mustacchi /* 394533affcbSRobert Mustacchi * The following errors indicate a bad lock type. 395533affcbSRobert Mustacchi */ 396533affcbSRobert Mustacchi NVME_IOCTL_E_BAD_LOCK_ENTITY, 397533affcbSRobert Mustacchi NVME_IOCTL_E_BAD_LOCK_LEVEL, 398533affcbSRobert Mustacchi NVME_IOCTL_E_BAD_LOCK_FLAGS, 399533affcbSRobert Mustacchi /* 400533affcbSRobert Mustacchi * Indicates that a namespace open cannot lock or unlock a controller. 401533affcbSRobert Mustacchi */ 402533affcbSRobert Mustacchi NVME_IOCTL_E_NS_CANNOT_LOCK_CTRL, 403533affcbSRobert Mustacchi NVME_IOCTL_E_NS_CANNOT_UNLOCK_CTRL, 404533affcbSRobert Mustacchi /* 405533affcbSRobert Mustacchi * Indicates that this lock is already held by the caller. 406533affcbSRobert Mustacchi */ 407533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_ALREADY_HELD, 408533affcbSRobert Mustacchi /* 409533affcbSRobert Mustacchi * Indicates that we cannot take the controller lock, because the 410533affcbSRobert Mustacchi * caller already has an active namespace lock. 411533affcbSRobert Mustacchi */ 412533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_NO_CTRL_WITH_NS, 413533affcbSRobert Mustacchi /* 414533affcbSRobert Mustacchi * Indicates that we cannot take a namespace lock because a controller 415533affcbSRobert Mustacchi * write lock already exists. 416533affcbSRobert Mustacchi */ 417533affcbSRobert Mustacchi NVME_IOCTL_LOCK_NO_NS_WITH_CTRL_WRLOCK, 418533affcbSRobert Mustacchi /* 419533affcbSRobert Mustacchi * Indicates that we cannot take a namespace lock because we already 420533affcbSRobert Mustacchi * have one. 421533affcbSRobert Mustacchi */ 422533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_NO_2ND_NS, 423533affcbSRobert Mustacchi /* 424533affcbSRobert Mustacchi * Indicate that a blocking wait for a lock was interrupted due to a 425533affcbSRobert Mustacchi * signal. 426533affcbSRobert Mustacchi */ 427533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_WAIT_SIGNAL, 428533affcbSRobert Mustacchi /* 429533affcbSRobert Mustacchi * Indicates that the lock could not be acquired because it was already 430533affcbSRobert Mustacchi * held and we were asked not to block on the lock. 431533affcbSRobert Mustacchi */ 432533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_WOULD_BLOCK, 433533affcbSRobert Mustacchi /* 434533affcbSRobert Mustacchi * Indicates that the lock operation could not proceed because the minor 435533affcbSRobert Mustacchi * is already blocking on another lock operation. 436533affcbSRobert Mustacchi */ 437533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_PENDING, 438533affcbSRobert Mustacchi /* 439533affcbSRobert Mustacchi * Indicates that the requested lock could not be unlocked because it is 440533affcbSRobert Mustacchi * not held. The minor may not hold the lock or it may be blocking for 441533affcbSRobert Mustacchi * acquisition. 442533affcbSRobert Mustacchi */ 443533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_NOT_HELD, 444533affcbSRobert Mustacchi /* 445533affcbSRobert Mustacchi * Indicates that the requested lock could not be unlocked because the 446533affcbSRobert Mustacchi * namespace requested is not the namespace that is currently locked. 447533affcbSRobert Mustacchi */ 448533affcbSRobert Mustacchi NVME_IOCTL_E_LOCK_WRONG_NS, 449533affcbSRobert Mustacchi /* 450533affcbSRobert Mustacchi * Indicates that the request could not proceed because a namespace is 451533affcbSRobert Mustacchi * attached to blkdev. This would block a format operation, a vendor 452533affcbSRobert Mustacchi * unique command that indicated that it would impact all namespaces, 453533affcbSRobert Mustacchi * etc. 454533affcbSRobert Mustacchi */ 455533affcbSRobert Mustacchi NVME_IOCTL_E_NS_BLKDEV_ATTACH, 456533affcbSRobert Mustacchi /* 457533affcbSRobert Mustacchi * Indicates that the blkdev address somehow would have overflowed our 458533affcbSRobert Mustacchi * internal buffer. 459533affcbSRobert Mustacchi */ 460533affcbSRobert Mustacchi NVME_IOCTL_E_BD_ADDR_OVER 461533affcbSRobert Mustacchi } nvme_ioctl_errno_t; 4623d9b1a2aSHans Rosenfeld 4633d9b1a2aSHans Rosenfeld /* 464533affcbSRobert Mustacchi * This structure is embedded as the first item of every ioctl. It is also used 465533affcbSRobert Mustacchi * directly for the attach (NVME_IOC_ATTACH) and detach (NVME_IOC_DETACH) 466533affcbSRobert Mustacchi * ioctls. 4673d9b1a2aSHans Rosenfeld */ 4683d9b1a2aSHans Rosenfeld typedef struct { 469533affcbSRobert Mustacchi /* 470533affcbSRobert Mustacchi * This allows one to specify the namespace ID that the ioctl may 471533affcbSRobert Mustacchi * target, if it supports it. This field may be left to zero to indicate 472533affcbSRobert Mustacchi * that the current open device (whether the controller or a namespace) 473533affcbSRobert Mustacchi * should be targeted. If a namespace is open, a value other than 0 or 474533affcbSRobert Mustacchi * the current namespace's ID is invalid. 475533affcbSRobert Mustacchi */ 476533affcbSRobert Mustacchi uint32_t nioc_nsid; 477533affcbSRobert Mustacchi /* 478533affcbSRobert Mustacchi * These next three values represent a possible error that may have 479533affcbSRobert Mustacchi * occurred. On every ioctl nioc_drv_err is set to a value from the 480533affcbSRobert Mustacchi * nvme_ioctl_errno_t enumeration. Anything other than NVME_IOCTL_E_OK 481533affcbSRobert Mustacchi * indicates a failure of some kind. Some error values will put 482533affcbSRobert Mustacchi * supplemental information in sct and sc. For example, 483533affcbSRobert Mustacchi * NVME_IOCTL_E_CTRL_ERROR uses that as a way to return the raw error 484533affcbSRobert Mustacchi * values from the controller for someone to inspect. Others may use 485533affcbSRobert Mustacchi * this for their own well-defined supplemental information. 486533affcbSRobert Mustacchi */ 487533affcbSRobert Mustacchi uint32_t nioc_drv_err; 488533affcbSRobert Mustacchi uint32_t nioc_ctrl_sct; 489533affcbSRobert Mustacchi uint32_t nioc_ctrl_sc; 490533affcbSRobert Mustacchi } nvme_ioctl_common_t; 491533affcbSRobert Mustacchi 492533affcbSRobert Mustacchi /* 493533affcbSRobert Mustacchi * NVMe Identify Command (NVME_IOC_IDENTIFY). 494533affcbSRobert Mustacchi */ 495533affcbSRobert Mustacchi typedef struct { 496533affcbSRobert Mustacchi nvme_ioctl_common_t nid_common; 497533affcbSRobert Mustacchi uint32_t nid_cns; 498533affcbSRobert Mustacchi uint32_t nid_ctrlid; 499533affcbSRobert Mustacchi uintptr_t nid_data; 500533affcbSRobert Mustacchi } nvme_ioctl_identify_t; 501533affcbSRobert Mustacchi 502533affcbSRobert Mustacchi /* 503533affcbSRobert Mustacchi * The following constants describe the maximum values that may be used in 504533affcbSRobert Mustacchi * various identify requests. 505533affcbSRobert Mustacchi */ 506533affcbSRobert Mustacchi #define NVME_IDENTIFY_MAX_CTRLID 0xffff 507533affcbSRobert Mustacchi #define NVME_IDENTIFY_MAX_NSID 0xffffffff 508533affcbSRobert Mustacchi #define NVME_IDENTIFY_MAX_CNS_1v2 0xff 509533affcbSRobert Mustacchi #define NVME_IDENTIFY_MAX_CNS_1v1 0x3 510533affcbSRobert Mustacchi #define NVME_IDENTIFY_MAX_CNS 0x1 511533affcbSRobert Mustacchi 512533affcbSRobert Mustacchi /* 513533affcbSRobert Mustacchi * Get a specific feature (NVME_IOC_GET_FEATURE). 514533affcbSRobert Mustacchi */ 515533affcbSRobert Mustacchi typedef struct { 516533affcbSRobert Mustacchi nvme_ioctl_common_t nigf_common; 517533affcbSRobert Mustacchi uint32_t nigf_fid; 518533affcbSRobert Mustacchi uint32_t nigf_sel; 519533affcbSRobert Mustacchi uint32_t nigf_cdw11; 520533affcbSRobert Mustacchi uintptr_t nigf_data; 521533affcbSRobert Mustacchi uint64_t nigf_len; 522533affcbSRobert Mustacchi uint32_t nigf_cdw0; 523533affcbSRobert Mustacchi } nvme_ioctl_get_feature_t; 524533affcbSRobert Mustacchi 525533affcbSRobert Mustacchi /* 526533affcbSRobert Mustacchi * Feature maximums. 527533affcbSRobert Mustacchi */ 528533affcbSRobert Mustacchi #define NVME_FEAT_MAX_FID 0xff 529533affcbSRobert Mustacchi #define NVME_FEAT_MAX_SEL 0x3 530533affcbSRobert Mustacchi 531533affcbSRobert Mustacchi /* 532533affcbSRobert Mustacchi * Get a specific log page (NVME_IOC_GET_LOGPAGE). By default, unused fields 533533affcbSRobert Mustacchi * should be left at zero. the input data length is specified by nigl_len, in 534533affcbSRobert Mustacchi * bytes. The NVMe specification does not provide a way for a controller to 535533affcbSRobert Mustacchi * write less bytes than requested for a log page. It is undefined behavior if a 536533affcbSRobert Mustacchi * log page read requests more data than is supported. If this is successful, 537533affcbSRobert Mustacchi * nigl_len bytes will be copied out. 538533affcbSRobert Mustacchi */ 539533affcbSRobert Mustacchi typedef struct { 540533affcbSRobert Mustacchi nvme_ioctl_common_t nigl_common; 541533affcbSRobert Mustacchi uint32_t nigl_csi; 542533affcbSRobert Mustacchi uint32_t nigl_lid; 543533affcbSRobert Mustacchi uint32_t nigl_lsp; 544533affcbSRobert Mustacchi uint32_t nigl_lsi; 545533affcbSRobert Mustacchi uint32_t nigl_rae; 546533affcbSRobert Mustacchi uint64_t nigl_len; 547533affcbSRobert Mustacchi uint64_t nigl_offset; 548533affcbSRobert Mustacchi uintptr_t nigl_data; 549533affcbSRobert Mustacchi } nvme_ioctl_get_logpage_t; 550533affcbSRobert Mustacchi 551533affcbSRobert Mustacchi /* 552533affcbSRobert Mustacchi * The following constants describe the maximum values for fields that used in 553533affcbSRobert Mustacchi * the log page request. Note, some of these change with the version. These 554533affcbSRobert Mustacchi * values are inclusive. The default max is the lowest common value. Larger 555533affcbSRobert Mustacchi * values are included here. While these values are what the command set 556533affcbSRobert Mustacchi * maximums are, the device driver may support smaller minimums (e.g. for size). 557533affcbSRobert Mustacchi */ 558533affcbSRobert Mustacchi #define NVME_LOG_MAX_LID 0xff 559533affcbSRobert Mustacchi #define NVME_LOG_MAX_LSP 0x0f 560533affcbSRobert Mustacchi #define NVME_LOG_MAX_LSP_2v0 0x7f 561533affcbSRobert Mustacchi #define NVME_LOG_MAX_LSI 0xffff 562533affcbSRobert Mustacchi #define NVME_LOG_MAX_UUID 0x7f 563533affcbSRobert Mustacchi #define NVME_LOG_MAX_CSI 0xff 564533affcbSRobert Mustacchi #define NVME_LOG_MAX_RAE 0x1 565533affcbSRobert Mustacchi #define NVME_LOG_MAX_OFFSET UINT64_MAX 566533affcbSRobert Mustacchi 567533affcbSRobert Mustacchi /* 568533affcbSRobert Mustacchi * These maximum size values are inclusive like the others. The fields are 12 569533affcbSRobert Mustacchi * and 32-bits wide respectively, but are zero based. That is accounted for by 570533affcbSRobert Mustacchi * the shifts below. 571533affcbSRobert Mustacchi */ 572533affcbSRobert Mustacchi #define NVME_LOG_MAX_SIZE ((1ULL << 12ULL) * 4ULL) 573533affcbSRobert Mustacchi #define NVME_LOG_MAX_SIZE_1v2 ((1ULL << 32ULL) * 4ULL) 574533affcbSRobert Mustacchi 575533affcbSRobert Mustacchi /* 576533affcbSRobert Mustacchi * Inject a vendor-specific admin command (NVME_IOC_PASSTHRU). 577533affcbSRobert Mustacchi */ 578533affcbSRobert Mustacchi typedef struct { 579533affcbSRobert Mustacchi nvme_ioctl_common_t npc_common; /* NSID and status */ 580533affcbSRobert Mustacchi uint32_t npc_opcode; /* Command opcode. */ 581533affcbSRobert Mustacchi uint32_t npc_timeout; /* Command timeout, in seconds. */ 582533affcbSRobert Mustacchi uint32_t npc_flags; /* Flags for the command. */ 583533affcbSRobert Mustacchi uint32_t npc_impact; /* Impact information */ 584533affcbSRobert Mustacchi uint32_t npc_cdw0; /* Command-specific result DWord 0 */ 585533affcbSRobert Mustacchi uint32_t npc_cdw12; /* Command-specific DWord 12 */ 586533affcbSRobert Mustacchi uint32_t npc_cdw13; /* Command-specific DWord 13 */ 587533affcbSRobert Mustacchi uint32_t npc_cdw14; /* Command-specific DWord 14 */ 588533affcbSRobert Mustacchi uint32_t npc_cdw15; /* Command-specific DWord 15 */ 589533affcbSRobert Mustacchi uint64_t npc_buflen; /* Size of npc_buf. */ 590533affcbSRobert Mustacchi uintptr_t npc_buf; /* I/O source or destination */ 591533affcbSRobert Mustacchi } nvme_ioctl_passthru_t; 592533affcbSRobert Mustacchi 593533affcbSRobert Mustacchi /* 594533affcbSRobert Mustacchi * Constants for the passthru admin commands. Because the timeout is a kernel 595533affcbSRobert Mustacchi * property, we don't include that here. 596533affcbSRobert Mustacchi */ 597533affcbSRobert Mustacchi #define NVME_PASSTHRU_MIN_ADMIN_OPC 0xc0 598533affcbSRobert Mustacchi #define NVME_PASSTHRU_MAX_ADMIN_OPC 0xff 599533affcbSRobert Mustacchi 600533affcbSRobert Mustacchi /* Flags for NVMe passthru commands. */ 601533affcbSRobert Mustacchi #define NVME_PASSTHRU_READ 0x1 /* Read from device */ 602533affcbSRobert Mustacchi #define NVME_PASSTHRU_WRITE 0x2 /* Write to device */ 603533affcbSRobert Mustacchi 604533affcbSRobert Mustacchi /* 605533affcbSRobert Mustacchi * Impact information for NVMe passthru commands. The current impact flags are 606533affcbSRobert Mustacchi * defined as follows: 607533affcbSRobert Mustacchi * 608533affcbSRobert Mustacchi * NVME_IMPACT_NS This implies that one or all of the namespaces may be 609533affcbSRobert Mustacchi * changed. This command will rescan all namespace after 610533affcbSRobert Mustacchi * this occurs and update our state as a result. However, 611533affcbSRobert Mustacchi * this requires that all such namespaces not be attached 612533affcbSRobert Mustacchi * to blkdev to continue. 613533affcbSRobert Mustacchi */ 614533affcbSRobert Mustacchi #define NVME_IMPACT_NS 0x01 615533affcbSRobert Mustacchi 616533affcbSRobert Mustacchi 617533affcbSRobert Mustacchi /* 618533affcbSRobert Mustacchi * Firmware download (NVME_IOC_FIRMWARE_DOWNLOAD). 619533affcbSRobert Mustacchi */ 620533affcbSRobert Mustacchi typedef struct { 621533affcbSRobert Mustacchi nvme_ioctl_common_t fwl_common; 622533affcbSRobert Mustacchi uintptr_t fwl_buf; 623533affcbSRobert Mustacchi uint64_t fwl_len; 624533affcbSRobert Mustacchi uint64_t fwl_off; 625533affcbSRobert Mustacchi } nvme_ioctl_fw_load_t; 626533affcbSRobert Mustacchi 627533affcbSRobert Mustacchi /* 628533affcbSRobert Mustacchi * Firmware commit (NVME_IOC_FIRMWARE_COMMIT). This was previously called 629533affcbSRobert Mustacchi * firmware activate in earlier specification revisions. 630533affcbSRobert Mustacchi */ 631533affcbSRobert Mustacchi typedef struct { 632533affcbSRobert Mustacchi nvme_ioctl_common_t fwc_common; 633533affcbSRobert Mustacchi uint32_t fwc_slot; 634533affcbSRobert Mustacchi uint32_t fwc_action; 635533affcbSRobert Mustacchi } nvme_ioctl_fw_commit_t; 636533affcbSRobert Mustacchi 637533affcbSRobert Mustacchi /* 638533affcbSRobert Mustacchi * Format NVM command (NVME_IOC_FORMAT) 639533affcbSRobert Mustacchi */ 640533affcbSRobert Mustacchi typedef struct { 641533affcbSRobert Mustacchi nvme_ioctl_common_t nif_common; 642533affcbSRobert Mustacchi uint32_t nif_lbaf; 643533affcbSRobert Mustacchi uint32_t nif_ses; 644533affcbSRobert Mustacchi } nvme_ioctl_format_t; 645533affcbSRobert Mustacchi 646533affcbSRobert Mustacchi typedef enum { 647533affcbSRobert Mustacchi NVME_LOCK_E_CTRL = 1, 648533affcbSRobert Mustacchi NVME_LOCK_E_NS 649533affcbSRobert Mustacchi } nvme_lock_ent_t; 650533affcbSRobert Mustacchi 651533affcbSRobert Mustacchi typedef enum { 652533affcbSRobert Mustacchi NVME_LOCK_L_READ = 1, 653533affcbSRobert Mustacchi NVME_LOCK_L_WRITE 654533affcbSRobert Mustacchi } nvme_lock_level_t; 655533affcbSRobert Mustacchi 656533affcbSRobert Mustacchi typedef enum { 657533affcbSRobert Mustacchi NVME_LOCK_F_DONT_BLOCK = 1 << 0 658533affcbSRobert Mustacchi } nvme_lock_flags_t; 659533affcbSRobert Mustacchi 660533affcbSRobert Mustacchi /* 661533affcbSRobert Mustacchi * Lock structure (NVME_IOC_LOCK). 662533affcbSRobert Mustacchi */ 663533affcbSRobert Mustacchi typedef struct { 664533affcbSRobert Mustacchi nvme_ioctl_common_t nil_common; 665533affcbSRobert Mustacchi nvme_lock_ent_t nil_ent; 666533affcbSRobert Mustacchi nvme_lock_level_t nil_level; 667533affcbSRobert Mustacchi nvme_lock_flags_t nil_flags; 668533affcbSRobert Mustacchi } nvme_ioctl_lock_t; 669533affcbSRobert Mustacchi 670533affcbSRobert Mustacchi /* 671533affcbSRobert Mustacchi * Unlock structure (NVME_IOC_UNLOCK). 672533affcbSRobert Mustacchi */ 673533affcbSRobert Mustacchi typedef struct { 674533affcbSRobert Mustacchi nvme_ioctl_common_t niu_common; 675533affcbSRobert Mustacchi nvme_lock_ent_t niu_ent; 676533affcbSRobert Mustacchi } nvme_ioctl_unlock_t; 677533affcbSRobert Mustacchi 678533affcbSRobert Mustacchi /* 679533affcbSRobert Mustacchi * 32-bit ioctl structures. These must be packed to be 4 bytes to get the proper 680533affcbSRobert Mustacchi * ILP32 sizing. 681533affcbSRobert Mustacchi */ 682533affcbSRobert Mustacchi #if defined(_KERNEL) && defined(_SYSCALL32) 683533affcbSRobert Mustacchi #pragma pack(4) 684533affcbSRobert Mustacchi typedef struct { 685533affcbSRobert Mustacchi nvme_ioctl_common_t nid_common; 686533affcbSRobert Mustacchi uint32_t nid_cns; 687533affcbSRobert Mustacchi uint32_t nid_ctrlid; 688533affcbSRobert Mustacchi uintptr32_t nid_data; 689533affcbSRobert Mustacchi } nvme_ioctl_identify32_t; 690533affcbSRobert Mustacchi 691533affcbSRobert Mustacchi typedef struct { 692533affcbSRobert Mustacchi nvme_ioctl_common_t nigf_common; 693533affcbSRobert Mustacchi uint32_t nigf_fid; 694533affcbSRobert Mustacchi uint32_t nigf_sel; 695533affcbSRobert Mustacchi uint32_t nigf_cdw11; 696533affcbSRobert Mustacchi uintptr32_t nigf_data; 697533affcbSRobert Mustacchi uint64_t nigf_len; 698533affcbSRobert Mustacchi uint32_t nigf_cdw0; 699533affcbSRobert Mustacchi } nvme_ioctl_get_feature32_t; 700533affcbSRobert Mustacchi 701533affcbSRobert Mustacchi typedef struct { 702533affcbSRobert Mustacchi nvme_ioctl_common_t nigl_common; 703533affcbSRobert Mustacchi uint32_t nigl_csi; 704533affcbSRobert Mustacchi uint32_t nigl_lid; 705533affcbSRobert Mustacchi uint32_t nigl_lsp; 706533affcbSRobert Mustacchi uint32_t nigl_lsi; 707533affcbSRobert Mustacchi uint32_t nigl_rae; 708533affcbSRobert Mustacchi uint64_t nigl_len; 709533affcbSRobert Mustacchi uint64_t nigl_offset; 710533affcbSRobert Mustacchi uintptr32_t nigl_data; 711533affcbSRobert Mustacchi } nvme_ioctl_get_logpage32_t; 712533affcbSRobert Mustacchi 713533affcbSRobert Mustacchi typedef struct { 714533affcbSRobert Mustacchi nvme_ioctl_common_t npc_common; /* NSID and status */ 715533affcbSRobert Mustacchi uint32_t npc_opcode; /* Command opcode. */ 716533affcbSRobert Mustacchi uint32_t npc_timeout; /* Command timeout, in seconds. */ 717533affcbSRobert Mustacchi uint32_t npc_flags; /* Flags for the command. */ 718533affcbSRobert Mustacchi uint32_t npc_impact; /* Impact information */ 719533affcbSRobert Mustacchi uint32_t npc_cdw0; /* Command-specific result DWord 0 */ 720533affcbSRobert Mustacchi uint32_t npc_cdw12; /* Command-specific DWord 12 */ 721533affcbSRobert Mustacchi uint32_t npc_cdw13; /* Command-specific DWord 13 */ 722533affcbSRobert Mustacchi uint32_t npc_cdw14; /* Command-specific DWord 14 */ 723533affcbSRobert Mustacchi uint32_t npc_cdw15; /* Command-specific DWord 15 */ 724533affcbSRobert Mustacchi uint64_t npc_buflen; /* Size of npc_buf. */ 725533affcbSRobert Mustacchi uintptr32_t npc_buf; /* I/O source or destination */ 726533affcbSRobert Mustacchi } nvme_ioctl_passthru32_t; 727533affcbSRobert Mustacchi 728533affcbSRobert Mustacchi typedef struct { 729533affcbSRobert Mustacchi nvme_ioctl_common_t fwl_common; 730533affcbSRobert Mustacchi uintptr32_t fwl_buf; 731533affcbSRobert Mustacchi uint64_t fwl_len; 732533affcbSRobert Mustacchi uint64_t fwl_off; 733533affcbSRobert Mustacchi } nvme_ioctl_fw_load32_t; 734533affcbSRobert Mustacchi #pragma pack() /* pack(4) */ 735533affcbSRobert Mustacchi #endif /* _KERNEL && _SYSCALL32 */ 736533affcbSRobert Mustacchi 737533affcbSRobert Mustacchi /* 738533affcbSRobert Mustacchi * NVMe capabilities. This is a set of fields that come from the controller's 739533affcbSRobert Mustacchi * PCIe register space. 740533affcbSRobert Mustacchi */ 741533affcbSRobert Mustacchi typedef struct { 742533affcbSRobert Mustacchi uint32_t cap_mpsmax; /* Memory Page Size Maximum */ 743533affcbSRobert Mustacchi uint32_t cap_mpsmin; /* Memory Page Size Minimum */ 7443d9b1a2aSHans Rosenfeld } nvme_capabilities_t; 7453d9b1a2aSHans Rosenfeld 7463d9b1a2aSHans Rosenfeld /* 7473d9b1a2aSHans Rosenfeld * NVMe version 7483d9b1a2aSHans Rosenfeld */ 7493d9b1a2aSHans Rosenfeld typedef struct { 7503d9b1a2aSHans Rosenfeld uint16_t v_minor; 7513d9b1a2aSHans Rosenfeld uint16_t v_major; 7523d9b1a2aSHans Rosenfeld } nvme_version_t; 7533d9b1a2aSHans Rosenfeld 7543d9b1a2aSHans Rosenfeld #define NVME_VERSION_ATLEAST(v, maj, min) \ 7553d9b1a2aSHans Rosenfeld (((v)->v_major) > (maj) || \ 7563d9b1a2aSHans Rosenfeld ((v)->v_major == (maj) && (v)->v_minor >= (min))) 7573d9b1a2aSHans Rosenfeld 7583d9b1a2aSHans Rosenfeld #define NVME_VERSION_HIGHER(v, maj, min) \ 7593d9b1a2aSHans Rosenfeld (((v)->v_major) > (maj) || \ 7603d9b1a2aSHans Rosenfeld ((v)->v_major == (maj) && (v)->v_minor > (min))) 7613d9b1a2aSHans Rosenfeld 762533affcbSRobert Mustacchi /* 763533affcbSRobert Mustacchi * NVMe Namespace related constants. The maximum NSID is determined by the 764533affcbSRobert Mustacchi * identify controller data structure. 765533affcbSRobert Mustacchi */ 766533affcbSRobert Mustacchi #define NVME_NSID_MIN 1 767533affcbSRobert Mustacchi #define NVME_NSID_BCAST 0xffffffff 7683d9b1a2aSHans Rosenfeld 7693d9b1a2aSHans Rosenfeld #pragma pack(1) 7703d9b1a2aSHans Rosenfeld 7718d5300d3SRobert Mustacchi typedef struct { 7728d5300d3SRobert Mustacchi uint64_t lo; 7738d5300d3SRobert Mustacchi uint64_t hi; 7748d5300d3SRobert Mustacchi } nvme_uint128_t; 7758d5300d3SRobert Mustacchi 7763d9b1a2aSHans Rosenfeld /* 7773d9b1a2aSHans Rosenfeld * NVMe Identify data structures 7783d9b1a2aSHans Rosenfeld */ 7793d9b1a2aSHans Rosenfeld 7803d9b1a2aSHans Rosenfeld #define NVME_IDENTIFY_BUFSIZE 4096 /* buffer size for Identify */ 7813d9b1a2aSHans Rosenfeld 782153f3212SHans Rosenfeld /* NVMe Identify parameters (cdw10) */ 783153f3212SHans Rosenfeld #define NVME_IDENTIFY_NSID 0x0 /* Identify Namespace */ 784153f3212SHans Rosenfeld #define NVME_IDENTIFY_CTRL 0x1 /* Identify Controller */ 785153f3212SHans Rosenfeld #define NVME_IDENTIFY_NSID_LIST 0x2 /* List Active Namespaces */ 786153f3212SHans Rosenfeld #define NVME_IDENTIFY_NSID_DESC 0x3 /* Namespace ID Descriptors */ 787153f3212SHans Rosenfeld 788153f3212SHans Rosenfeld #define NVME_IDENTIFY_NSID_ALLOC_LIST 0x10 /* List Allocated NSID */ 789153f3212SHans Rosenfeld #define NVME_IDENTIFY_NSID_ALLOC 0x11 /* Identify Allocated NSID */ 790153f3212SHans Rosenfeld #define NVME_IDENTIFY_NSID_CTRL_LIST 0x12 /* List Controllers on NSID */ 791153f3212SHans Rosenfeld #define NVME_IDENTIFY_CTRL_LIST 0x13 /* Controller List */ 792153f3212SHans Rosenfeld #define NVME_IDENTIFY_PRIMARY_CAPS 0x14 /* Primary Controller Caps */ 793153f3212SHans Rosenfeld 794153f3212SHans Rosenfeld 7953d9b1a2aSHans Rosenfeld /* NVMe Queue Entry Size bitfield */ 7963d9b1a2aSHans Rosenfeld typedef struct { 7973d9b1a2aSHans Rosenfeld uint8_t qes_min:4; /* minimum entry size */ 7983d9b1a2aSHans Rosenfeld uint8_t qes_max:4; /* maximum entry size */ 7993d9b1a2aSHans Rosenfeld } nvme_idctl_qes_t; 8003d9b1a2aSHans Rosenfeld 8013d9b1a2aSHans Rosenfeld /* NVMe Power State Descriptor */ 8023d9b1a2aSHans Rosenfeld typedef struct { 8033d9b1a2aSHans Rosenfeld uint16_t psd_mp; /* Maximum Power */ 8043d9b1a2aSHans Rosenfeld uint8_t psd_rsvd1; 8053d9b1a2aSHans Rosenfeld uint8_t psd_mps:1; /* Max Power Scale (1.1) */ 8063d9b1a2aSHans Rosenfeld uint8_t psd_nops:1; /* Non-Operational State (1.1) */ 8073d9b1a2aSHans Rosenfeld uint8_t psd_rsvd2:6; 8083d9b1a2aSHans Rosenfeld uint32_t psd_enlat; /* Entry Latency */ 8093d9b1a2aSHans Rosenfeld uint32_t psd_exlat; /* Exit Latency */ 8103d9b1a2aSHans Rosenfeld uint8_t psd_rrt:5; /* Relative Read Throughput */ 8113d9b1a2aSHans Rosenfeld uint8_t psd_rsvd3:3; 8123d9b1a2aSHans Rosenfeld uint8_t psd_rrl:5; /* Relative Read Latency */ 8133d9b1a2aSHans Rosenfeld uint8_t psd_rsvd4:3; 8143d9b1a2aSHans Rosenfeld uint8_t psd_rwt:5; /* Relative Write Throughput */ 8153d9b1a2aSHans Rosenfeld uint8_t psd_rsvd5:3; 8163d9b1a2aSHans Rosenfeld uint8_t psd_rwl:5; /* Relative Write Latency */ 8173d9b1a2aSHans Rosenfeld uint8_t psd_rsvd6:3; 81848d370f1SRobert Mustacchi uint16_t psd_idlp; /* Idle Power (1.2) */ 81948d370f1SRobert Mustacchi uint8_t psd_rsvd7:6; 82048d370f1SRobert Mustacchi uint8_t psd_ips:2; /* Idle Power Scale (1.2) */ 82148d370f1SRobert Mustacchi uint8_t psd_rsvd8; 82248d370f1SRobert Mustacchi uint16_t psd_actp; /* Active Power (1.2) */ 82348d370f1SRobert Mustacchi uint8_t psd_apw:3; /* Active Power Workload (1.2) */ 82448d370f1SRobert Mustacchi uint8_t psd_rsvd9:3; 82548d370f1SRobert Mustacchi uint8_t psd_aps:2; /* Active Power Scale */ 82648d370f1SRobert Mustacchi uint8_t psd_rsvd10[9]; 8273d9b1a2aSHans Rosenfeld } nvme_idctl_psd_t; 8283d9b1a2aSHans Rosenfeld 8293c6ffbabSRob Johnston #define NVME_SERIAL_SZ 20 8303c6ffbabSRob Johnston #define NVME_MODEL_SZ 40 831533affcbSRobert Mustacchi #define NVME_FWVER_SZ 8 8323c6ffbabSRob Johnston 8333d9b1a2aSHans Rosenfeld /* NVMe Identify Controller Data Structure */ 8343d9b1a2aSHans Rosenfeld typedef struct { 8353d9b1a2aSHans Rosenfeld /* Controller Capabilities & Features */ 8363d9b1a2aSHans Rosenfeld uint16_t id_vid; /* PCI vendor ID */ 8373d9b1a2aSHans Rosenfeld uint16_t id_ssvid; /* PCI subsystem vendor ID */ 8383c6ffbabSRob Johnston char id_serial[NVME_SERIAL_SZ]; /* Serial Number */ 8393c6ffbabSRob Johnston char id_model[NVME_MODEL_SZ]; /* Model Number */ 840533affcbSRobert Mustacchi char id_fwrev[NVME_FWVER_SZ]; /* Firmware Revision */ 8413d9b1a2aSHans Rosenfeld uint8_t id_rab; /* Recommended Arbitration Burst */ 8423d9b1a2aSHans Rosenfeld uint8_t id_oui[3]; /* vendor IEEE OUI */ 8433d9b1a2aSHans Rosenfeld struct { /* Multi-Interface Capabilities */ 8443d9b1a2aSHans Rosenfeld uint8_t m_multi_pci:1; /* HW has multiple PCIe interfaces */ 8453d9b1a2aSHans Rosenfeld uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */ 8468d5300d3SRobert Mustacchi uint8_t m_sr_iov:1; /* Controller is SR-IOV virt fn (1.1) */ 8478d5300d3SRobert Mustacchi uint8_t m_anar_sup:1; /* ANA Reporting Supported (1.4) */ 8488d5300d3SRobert Mustacchi uint8_t m_rsvd:4; 8493d9b1a2aSHans Rosenfeld } id_mic; 8503d9b1a2aSHans Rosenfeld uint8_t id_mdts; /* Maximum Data Transfer Size */ 8513d9b1a2aSHans Rosenfeld uint16_t id_cntlid; /* Unique Controller Identifier (1.1) */ 85248d370f1SRobert Mustacchi /* Added in NVMe 1.2 */ 8538d5300d3SRobert Mustacchi uint32_t id_ver; /* Version (1.2) */ 8548d5300d3SRobert Mustacchi uint32_t id_rtd3r; /* RTD3 Resume Latency (1.2) */ 8558d5300d3SRobert Mustacchi uint32_t id_rtd3e; /* RTD3 Entry Latency (1.2) */ 8568d5300d3SRobert Mustacchi struct { 8578d5300d3SRobert Mustacchi uint32_t oaes_rsvd0:8; 8588d5300d3SRobert Mustacchi uint32_t oaes_nsan:1; /* Namespace Attribute Notices (1.2) */ 8598d5300d3SRobert Mustacchi uint32_t oaes_fwact:1; /* Firmware Activation Notices (1.2) */ 8608d5300d3SRobert Mustacchi uint32_t oaes_rsvd1:1; 8618d5300d3SRobert Mustacchi uint32_t oaes_ansacn:1; /* Asymmetric NS Access Change (1.4) */ 8628d5300d3SRobert Mustacchi uint32_t oaes_plat:1; /* Predictable Lat Event Agg. (1.4) */ 8638d5300d3SRobert Mustacchi uint32_t oaes_lbasi:1; /* LBA Status Information (1.4) */ 8648d5300d3SRobert Mustacchi uint32_t oaes_egeal:1; /* Endurance Group Event Agg. (1.4) */ 8658d5300d3SRobert Mustacchi uint32_t oaes_rsvd2:17; 8668d5300d3SRobert Mustacchi } id_oaes; 8678d5300d3SRobert Mustacchi struct { 8688d5300d3SRobert Mustacchi uint32_t ctrat_hid:1; /* 128-bit Host Identifier (1.2) */ 8698d5300d3SRobert Mustacchi uint32_t ctrat_nops:1; /* Non-Operational Power State (1.3) */ 8708d5300d3SRobert Mustacchi uint32_t ctrat_nvmset:1; /* NVMe Sets (1.4) */ 8718d5300d3SRobert Mustacchi uint32_t ctrat_rrl:1; /* Read Recovery Levels (1.4) */ 8728d5300d3SRobert Mustacchi uint32_t ctrat_engrp:1; /* Endurance Groups (1.4) */ 8738d5300d3SRobert Mustacchi uint32_t ctrat_plm:1; /* Predictable Latency Mode (1.4) */ 8748d5300d3SRobert Mustacchi uint32_t ctrat_tbkas:1; /* Traffic Based Keep Alive (1.4) */ 8758d5300d3SRobert Mustacchi uint32_t ctrat_nsg:1; /* Namespace Granularity (1.4) */ 8768d5300d3SRobert Mustacchi uint32_t ctrat_sqass:1; /* SQ Associations (1.4) */ 8778d5300d3SRobert Mustacchi uint32_t ctrat_uuid:1; /* UUID List (1.4) */ 8788d5300d3SRobert Mustacchi uint32_t ctrat_rsvd:22; 8798d5300d3SRobert Mustacchi } id_ctratt; 8808d5300d3SRobert Mustacchi uint16_t id_rrls; /* Read Recovery Levels (1.4) */ 8818d5300d3SRobert Mustacchi uint8_t id_rsvd_cc[111-102]; 8828d5300d3SRobert Mustacchi uint8_t id_cntrltype; /* Controller Type (1.4) */ 8838d5300d3SRobert Mustacchi uint8_t id_frguid[16]; /* FRU GUID (1.3) */ 8848d5300d3SRobert Mustacchi uint16_t id_crdt1; /* Command Retry Delay Time 1 (1.4) */ 8858d5300d3SRobert Mustacchi uint16_t id_crdt2; /* Command Retry Delay Time 2 (1.4) */ 8868d5300d3SRobert Mustacchi uint16_t id_crdt3; /* Command Retry Delay Time 3 (1.4) */ 8878d5300d3SRobert Mustacchi uint8_t id_rsvd2_cc[240 - 134]; 8888d5300d3SRobert Mustacchi uint8_t id_rsvd_nvmemi[253 - 240]; 8898d5300d3SRobert Mustacchi /* NVMe-MI region */ 8908d5300d3SRobert Mustacchi struct { /* NVMe Subsystem Report */ 8918d5300d3SRobert Mustacchi uint8_t nvmsr_nvmesd:1; /* NVMe Storage Device */ 8928d5300d3SRobert Mustacchi uint8_t nvmsr_nvmee:1; /* NVMe Enclosure */ 8938d5300d3SRobert Mustacchi uint8_t nvmsr_rsvd:6; 8948d5300d3SRobert Mustacchi } id_nvmsr; 8958d5300d3SRobert Mustacchi struct { /* VPD Write Cycle Information */ 8968d5300d3SRobert Mustacchi uint8_t vwci_crem:7; /* Write Cycles Remaining */ 8978d5300d3SRobert Mustacchi uint8_t vwci_valid:1; /* Write Cycles Remaining Valid */ 8988d5300d3SRobert Mustacchi } id_vpdwc; 8998d5300d3SRobert Mustacchi struct { /* Management Endpoint Capabilities */ 9008d5300d3SRobert Mustacchi uint8_t mec_smbusme:1; /* SMBus Port Management Endpoint */ 9018d5300d3SRobert Mustacchi uint8_t mec_pcieme:1; /* PCIe Port Management Endpoint */ 9028d5300d3SRobert Mustacchi uint8_t mec_rsvd:6; 9038d5300d3SRobert Mustacchi } id_mec; 9043d9b1a2aSHans Rosenfeld 9053d9b1a2aSHans Rosenfeld /* Admin Command Set Attributes */ 9063d9b1a2aSHans Rosenfeld struct { /* Optional Admin Command Support */ 9073d9b1a2aSHans Rosenfeld uint16_t oa_security:1; /* Security Send & Receive */ 9083d9b1a2aSHans Rosenfeld uint16_t oa_format:1; /* Format NVM */ 9093d9b1a2aSHans Rosenfeld uint16_t oa_firmware:1; /* Firmware Activate & Download */ 9108d5300d3SRobert Mustacchi uint16_t oa_nsmgmt:1; /* Namespace Management (1.2) */ 9118d5300d3SRobert Mustacchi uint16_t oa_selftest:1; /* Self Test (1.3) */ 9128d5300d3SRobert Mustacchi uint16_t oa_direct:1; /* Directives (1.3) */ 9138d5300d3SRobert Mustacchi uint16_t oa_nvmemi:1; /* MI-Send/Recv (1.3) */ 9148d5300d3SRobert Mustacchi uint16_t oa_virtmgmt:1; /* Virtualization Management (1.3) */ 9158d5300d3SRobert Mustacchi uint16_t oa_doorbell:1; /* Doorbell Buffer Config (1.3) */ 9168d5300d3SRobert Mustacchi uint16_t oa_lbastat:1; /* LBA Status (1.4) */ 9178d5300d3SRobert Mustacchi uint16_t oa_rsvd:6; 9183d9b1a2aSHans Rosenfeld } id_oacs; 9193d9b1a2aSHans Rosenfeld uint8_t id_acl; /* Abort Command Limit */ 9203d9b1a2aSHans Rosenfeld uint8_t id_aerl; /* Asynchronous Event Request Limit */ 9213d9b1a2aSHans Rosenfeld struct { /* Firmware Updates */ 9223d9b1a2aSHans Rosenfeld uint8_t fw_readonly:1; /* Slot 1 is Read-Only */ 9233d9b1a2aSHans Rosenfeld uint8_t fw_nslot:3; /* number of firmware slots */ 9248d5300d3SRobert Mustacchi uint8_t fw_norst:1; /* Activate w/o reset (1.2) */ 9258d5300d3SRobert Mustacchi uint8_t fw_rsvd:3; 9263d9b1a2aSHans Rosenfeld } id_frmw; 9273d9b1a2aSHans Rosenfeld struct { /* Log Page Attributes */ 9283d9b1a2aSHans Rosenfeld uint8_t lp_smart:1; /* SMART/Health information per NS */ 9298d5300d3SRobert Mustacchi uint8_t lp_cmdeff:1; /* Command Effects (1.2) */ 9308d5300d3SRobert Mustacchi uint8_t lp_extsup:1; /* Extended Get Log Page (1.2) */ 9318d5300d3SRobert Mustacchi uint8_t lp_telemetry:1; /* Telemetry Log Pages (1.3) */ 9328d5300d3SRobert Mustacchi uint8_t lp_persist:1; /* Persistent Log Page (1.4) */ 9338d5300d3SRobert Mustacchi uint8_t lp_rsvd:3; 9343d9b1a2aSHans Rosenfeld } id_lpa; 9353d9b1a2aSHans Rosenfeld uint8_t id_elpe; /* Error Log Page Entries */ 9363d9b1a2aSHans Rosenfeld uint8_t id_npss; /* Number of Power States */ 9373d9b1a2aSHans Rosenfeld struct { /* Admin Vendor Specific Command Conf */ 9383d9b1a2aSHans Rosenfeld uint8_t av_spec:1; /* use format from spec */ 9393d9b1a2aSHans Rosenfeld uint8_t av_rsvd:7; 9403d9b1a2aSHans Rosenfeld } id_avscc; 9413d9b1a2aSHans Rosenfeld struct { /* Autonomous Power State Trans (1.1) */ 9423d9b1a2aSHans Rosenfeld uint8_t ap_sup:1; /* APST supported (1.1) */ 9433d9b1a2aSHans Rosenfeld uint8_t ap_rsvd:7; 9443d9b1a2aSHans Rosenfeld } id_apsta; 9458d5300d3SRobert Mustacchi uint16_t ap_wctemp; /* Warning Composite Temp. (1.2) */ 9468d5300d3SRobert Mustacchi uint16_t ap_cctemp; /* Critical Composite Temp. (1.2) */ 9478d5300d3SRobert Mustacchi uint16_t ap_mtfa; /* Maximum Firmware Activation (1.2) */ 9488d5300d3SRobert Mustacchi uint32_t ap_hmpre; /* Host Memory Buf Pref Size (1.2) */ 9498d5300d3SRobert Mustacchi uint32_t ap_hmmin; /* Host Memory Buf Min Size (1.2) */ 9508d5300d3SRobert Mustacchi nvme_uint128_t ap_tnvmcap; /* Total NVM Capacity in Bytes (1.2) */ 9518d5300d3SRobert Mustacchi nvme_uint128_t ap_unvmcap; /* Unallocated NVM Capacity (1.2) */ 9528d5300d3SRobert Mustacchi struct { /* Replay Protected Mem. Block (1.2) */ 9538d5300d3SRobert Mustacchi uint32_t rpmbs_units:3; /* Number of targets */ 9548d5300d3SRobert Mustacchi uint32_t rpmbs_auth:3; /* Auth method */ 9558d5300d3SRobert Mustacchi uint32_t rpmbs_rsvd:10; 9568d5300d3SRobert Mustacchi uint32_t rpmbs_tot:8; /* Total size in 128KB */ 9578d5300d3SRobert Mustacchi uint32_t rpmbs_acc:8; /* Access size in 512B */ 9588d5300d3SRobert Mustacchi } ap_rpmbs; 95948d370f1SRobert Mustacchi /* Added in NVMe 1.3 */ 9608d5300d3SRobert Mustacchi uint16_t ap_edstt; /* Ext. Device Self-test time (1.3) */ 9618d5300d3SRobert Mustacchi struct { /* Device Self-test Options */ 9628d5300d3SRobert Mustacchi uint8_t dsto_sub:1; /* Subsystem level self-test (1.3) */ 9638d5300d3SRobert Mustacchi uint8_t dsto_rsvd:7; 9648d5300d3SRobert Mustacchi } ap_dsto; 9658d5300d3SRobert Mustacchi uint8_t ap_fwug; /* Firmware Update Granularity (1.3) */ 9668d5300d3SRobert Mustacchi uint16_t ap_kas; /* Keep Alive Support (1.2) */ 9678d5300d3SRobert Mustacchi struct { /* Host Thermal Management (1.3) */ 9688d5300d3SRobert Mustacchi uint16_t hctma_hctm:1; /* Host Controlled (1.3) */ 9698d5300d3SRobert Mustacchi uint16_t hctma_rsvd:15; 9708d5300d3SRobert Mustacchi } ap_hctma; 9718d5300d3SRobert Mustacchi uint16_t ap_mntmt; /* Minimum Thermal Temperature (1.3) */ 9728d5300d3SRobert Mustacchi uint16_t ap_mxtmt; /* Maximum Thermal Temperature (1.3) */ 9738d5300d3SRobert Mustacchi struct { /* Sanitize Caps */ 9748d5300d3SRobert Mustacchi uint32_t san_ces:1; /* Crypto Erase Support (1.3) */ 9758d5300d3SRobert Mustacchi uint32_t san_bes:1; /* Block Erase Support (1.3) */ 9768d5300d3SRobert Mustacchi uint32_t san_ows:1; /* Overwite Support (1.3) */ 9778d5300d3SRobert Mustacchi uint32_t san_rsvd:26; 9788d5300d3SRobert Mustacchi uint32_t san_ndi:1; /* No-deallocate Inhibited (1.4) */ 9798d5300d3SRobert Mustacchi uint32_t san_nodmmas:2; /* No-Deallocate Modifies Media (1.4) */ 9808d5300d3SRobert Mustacchi } ap_sanitize; 9818d5300d3SRobert Mustacchi uint32_t ap_hmminds; /* Host Mem Buf Min Desc Entry (1.4) */ 9828d5300d3SRobert Mustacchi uint16_t ap_hmmaxd; /* How Mem Max Desc Entries (1.4) */ 9838d5300d3SRobert Mustacchi uint16_t ap_nsetidmax; /* Max NVMe set identifier (1.4) */ 9848d5300d3SRobert Mustacchi uint16_t ap_engidmax; /* Max Endurance Group ID (1.4) */ 9858d5300d3SRobert Mustacchi uint8_t ap_anatt; /* ANA Transition Time (1.4) */ 9868d5300d3SRobert Mustacchi struct { /* Asymmetric Namespace Access Caps */ 9878d5300d3SRobert Mustacchi uint8_t anacap_opt:1; /* Optimized State (1.4) */ 9888d5300d3SRobert Mustacchi uint8_t anacap_unopt:1; /* Un-optimized State (1.4) */ 9898d5300d3SRobert Mustacchi uint8_t anacap_inacc:1; /* Inaccessible State (1.4) */ 9908d5300d3SRobert Mustacchi uint8_t anacap_ploss:1; /* Persistent Loss (1.4) */ 9918d5300d3SRobert Mustacchi uint8_t anacap_chg:1; /* Change State (1.4 ) */ 9928d5300d3SRobert Mustacchi uint8_t anacap_rsvd:1; 9938d5300d3SRobert Mustacchi uint8_t anacap_grpns:1; /* ID Changes with NS Attach (1.4) */ 9948d5300d3SRobert Mustacchi uint8_t anacap_grpid:1; /* Supports Group ID (1.4) */ 9958d5300d3SRobert Mustacchi } ap_anacap; 9968d5300d3SRobert Mustacchi uint32_t ap_anagrpmax; /* ANA Group ID Max (1.4) */ 9978d5300d3SRobert Mustacchi uint32_t ap_nanagrpid; /* Number of ANA Group IDs (1.4) */ 9988d5300d3SRobert Mustacchi uint32_t ap_pels; /* Persistent Event Log Size (1.4) */ 9998d5300d3SRobert Mustacchi uint8_t id_rsvd_ac[512 - 356]; 10003d9b1a2aSHans Rosenfeld 10013d9b1a2aSHans Rosenfeld /* NVM Command Set Attributes */ 10023d9b1a2aSHans Rosenfeld nvme_idctl_qes_t id_sqes; /* Submission Queue Entry Size */ 10033d9b1a2aSHans Rosenfeld nvme_idctl_qes_t id_cqes; /* Completion Queue Entry Size */ 100448d370f1SRobert Mustacchi uint16_t id_maxcmd; /* Max Outstanding Commands (1.3) */ 10053d9b1a2aSHans Rosenfeld uint32_t id_nn; /* Number of Namespaces */ 10063d9b1a2aSHans Rosenfeld struct { /* Optional NVM Command Support */ 10073d9b1a2aSHans Rosenfeld uint16_t on_compare:1; /* Compare */ 10083d9b1a2aSHans Rosenfeld uint16_t on_wr_unc:1; /* Write Uncorrectable */ 10093d9b1a2aSHans Rosenfeld uint16_t on_dset_mgmt:1; /* Dataset Management */ 10103d9b1a2aSHans Rosenfeld uint16_t on_wr_zero:1; /* Write Zeros (1.1) */ 10113d9b1a2aSHans Rosenfeld uint16_t on_save:1; /* Save/Select in Get/Set Feat (1.1) */ 10123d9b1a2aSHans Rosenfeld uint16_t on_reserve:1; /* Reservations (1.1) */ 10138d5300d3SRobert Mustacchi uint16_t on_ts:1; /* Timestamp (1.3) */ 10148d5300d3SRobert Mustacchi uint16_t on_verify:1; /* Verify (1.4) */ 10158d5300d3SRobert Mustacchi uint16_t on_rsvd:8; 10163d9b1a2aSHans Rosenfeld } id_oncs; 10173d9b1a2aSHans Rosenfeld struct { /* Fused Operation Support */ 10183d9b1a2aSHans Rosenfeld uint16_t f_cmp_wr:1; /* Compare and Write */ 10193d9b1a2aSHans Rosenfeld uint16_t f_rsvd:15; 10203d9b1a2aSHans Rosenfeld } id_fuses; 10213d9b1a2aSHans Rosenfeld struct { /* Format NVM Attributes */ 10223d9b1a2aSHans Rosenfeld uint8_t fn_format:1; /* Format applies to all NS */ 10233d9b1a2aSHans Rosenfeld uint8_t fn_sec_erase:1; /* Secure Erase applies to all NS */ 10243d9b1a2aSHans Rosenfeld uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */ 10253d9b1a2aSHans Rosenfeld uint8_t fn_rsvd:5; 10263d9b1a2aSHans Rosenfeld } id_fna; 10273d9b1a2aSHans Rosenfeld struct { /* Volatile Write Cache */ 10283d9b1a2aSHans Rosenfeld uint8_t vwc_present:1; /* Volatile Write Cache present */ 10298d5300d3SRobert Mustacchi uint8_t vwc_nsflush:2; /* Flush with NS ffffffff (1.4) */ 10308d5300d3SRobert Mustacchi uint8_t rsvd:5; 10313d9b1a2aSHans Rosenfeld } id_vwc; 10323d9b1a2aSHans Rosenfeld uint16_t id_awun; /* Atomic Write Unit Normal */ 10333d9b1a2aSHans Rosenfeld uint16_t id_awupf; /* Atomic Write Unit Power Fail */ 10343d9b1a2aSHans Rosenfeld struct { /* NVM Vendor Specific Command Conf */ 10353d9b1a2aSHans Rosenfeld uint8_t nv_spec:1; /* use format from spec */ 10363d9b1a2aSHans Rosenfeld uint8_t nv_rsvd:7; 10373d9b1a2aSHans Rosenfeld } id_nvscc; 10388d5300d3SRobert Mustacchi struct { /* Namespace Write Protection Caps */ 10398d5300d3SRobert Mustacchi uint8_t nwpc_base:1; /* Base support (1.4) */ 10408d5300d3SRobert Mustacchi uint8_t nwpc_wpupc:1; /* Write prot until power cycle (1.4) */ 10418d5300d3SRobert Mustacchi uint8_t nwpc_permwp:1; /* Permanent write prot (1.4) */ 10428d5300d3SRobert Mustacchi uint8_t nwpc_rsvd:5; 10438d5300d3SRobert Mustacchi } id_nwpc; 10443d9b1a2aSHans Rosenfeld uint16_t id_acwu; /* Atomic Compare & Write Unit (1.1) */ 10453d9b1a2aSHans Rosenfeld uint16_t id_rsvd_nc_3; 10463d9b1a2aSHans Rosenfeld struct { /* SGL Support (1.1) */ 10478d5300d3SRobert Mustacchi uint16_t sgl_sup:2; /* SGL Supported in NVM cmds (1.3) */ 10488d5300d3SRobert Mustacchi uint16_t sgl_keyed:1; /* Keyed SGL Support (1.2) */ 10498d5300d3SRobert Mustacchi uint16_t sgl_rsvd1:13; 10503d9b1a2aSHans Rosenfeld uint16_t sgl_bucket:1; /* SGL Bit Bucket supported (1.1) */ 10518d5300d3SRobert Mustacchi uint16_t sgl_balign:1; /* SGL Byte Aligned (1.2) */ 10528d5300d3SRobert Mustacchi uint16_t sgl_sglgtd:1; /* SGL Length Longer than Data (1.2) */ 10538d5300d3SRobert Mustacchi uint16_t sgl_mptr:1; /* SGL MPTR w/ SGL (1.2) */ 10548d5300d3SRobert Mustacchi uint16_t sgl_offset:1; /* SGL Address is offset (1.2) */ 10558d5300d3SRobert Mustacchi uint16_t sgl_tport:1; /* Transport SGL Data Block (1.4) */ 10568d5300d3SRobert Mustacchi uint16_t sgl_rsvd2:10; 10573d9b1a2aSHans Rosenfeld } id_sgls; 105898f586d7SAndy Fiddaman uint32_t id_mnan; /* Maximum Number of Allowed NSes */ 10598d5300d3SRobert Mustacchi uint8_t id_rsvd_nc_4[768 - 544]; 10603d9b1a2aSHans Rosenfeld 10613d9b1a2aSHans Rosenfeld /* I/O Command Set Attributes */ 106248d370f1SRobert Mustacchi uint8_t id_subnqn[1024 - 768]; /* Subsystem Qualified Name (1.2.1+) */ 106348d370f1SRobert Mustacchi uint8_t id_rsvd_ioc[1792 - 1024]; 106448d370f1SRobert Mustacchi uint8_t id_nvmof[2048 - 1792]; /* NVMe over Fabrics */ 10653d9b1a2aSHans Rosenfeld 10663d9b1a2aSHans Rosenfeld /* Power State Descriptors */ 10673d9b1a2aSHans Rosenfeld nvme_idctl_psd_t id_psd[32]; 10683d9b1a2aSHans Rosenfeld 10693d9b1a2aSHans Rosenfeld /* Vendor Specific */ 10703d9b1a2aSHans Rosenfeld uint8_t id_vs[1024]; 10713d9b1a2aSHans Rosenfeld } nvme_identify_ctrl_t; 10723d9b1a2aSHans Rosenfeld 10738d5300d3SRobert Mustacchi /* 10748d5300d3SRobert Mustacchi * NVMe Controller Types 10758d5300d3SRobert Mustacchi */ 10768d5300d3SRobert Mustacchi #define NVME_CNTRLTYPE_RSVD 0 10778d5300d3SRobert Mustacchi #define NVME_CNTRLTYPE_IO 1 10788d5300d3SRobert Mustacchi #define NVME_CNTRLTYPE_DISC 2 10798d5300d3SRobert Mustacchi #define NVME_CNTRLTYPE_ADMIN 3 10808d5300d3SRobert Mustacchi 10818d5300d3SRobert Mustacchi /* 10828d5300d3SRobert Mustacchi * RPMBS Authentication Types 10838d5300d3SRobert Mustacchi */ 10848d5300d3SRobert Mustacchi #define NVME_RPMBS_AUTH_HMAC_SHA256 0 10858d5300d3SRobert Mustacchi 10868d5300d3SRobert Mustacchi /* 10878d5300d3SRobert Mustacchi * NODMMAS Values 10888d5300d3SRobert Mustacchi */ 10898d5300d3SRobert Mustacchi #define NVME_NODMMAS_UNDEF 0x00 10908d5300d3SRobert Mustacchi #define NVME_NODMMAS_NOMOD 0x01 10918d5300d3SRobert Mustacchi #define NVME_NODMMAS_DOMOD 0x02 10928d5300d3SRobert Mustacchi 10938d5300d3SRobert Mustacchi /* 10948d5300d3SRobert Mustacchi * VWC NSID flushes 10958d5300d3SRobert Mustacchi */ 10968d5300d3SRobert Mustacchi #define NVME_VWCNS_UNKNOWN 0x00 10978d5300d3SRobert Mustacchi #define NVME_VWCNS_UNSUP 0x02 10988d5300d3SRobert Mustacchi #define NVME_VWCNS_SUP 0x03 10998d5300d3SRobert Mustacchi 11008d5300d3SRobert Mustacchi /* 11018d5300d3SRobert Mustacchi * SGL Support Values 11028d5300d3SRobert Mustacchi */ 11038d5300d3SRobert Mustacchi #define NVME_SGL_UNSUP 0x00 11048d5300d3SRobert Mustacchi #define NVME_SGL_SUP_UNALIGN 0x01 11058d5300d3SRobert Mustacchi #define NVME_SGL_SUP_ALIGN 0x02 11068d5300d3SRobert Mustacchi 11073d9b1a2aSHans Rosenfeld /* NVMe Identify Namespace LBA Format */ 11083d9b1a2aSHans Rosenfeld typedef struct { 11093d9b1a2aSHans Rosenfeld uint16_t lbaf_ms; /* Metadata Size */ 11103d9b1a2aSHans Rosenfeld uint8_t lbaf_lbads; /* LBA Data Size */ 11113d9b1a2aSHans Rosenfeld uint8_t lbaf_rp:2; /* Relative Performance */ 11123d9b1a2aSHans Rosenfeld uint8_t lbaf_rsvd1:6; 11133d9b1a2aSHans Rosenfeld } nvme_idns_lbaf_t; 11143d9b1a2aSHans Rosenfeld 1115533affcbSRobert Mustacchi #define NVME_MAX_LBAF 16 1116533affcbSRobert Mustacchi 11173d9b1a2aSHans Rosenfeld /* NVMe Identify Namespace Data Structure */ 11183d9b1a2aSHans Rosenfeld typedef struct { 11193d9b1a2aSHans Rosenfeld uint64_t id_nsize; /* Namespace Size */ 11203d9b1a2aSHans Rosenfeld uint64_t id_ncap; /* Namespace Capacity */ 11213d9b1a2aSHans Rosenfeld uint64_t id_nuse; /* Namespace Utilization */ 11223d9b1a2aSHans Rosenfeld struct { /* Namespace Features */ 11233d9b1a2aSHans Rosenfeld uint8_t f_thin:1; /* Thin Provisioning */ 11248d5300d3SRobert Mustacchi uint8_t f_nsabp:1; /* Namespace atomics (1.2) */ 11258d5300d3SRobert Mustacchi uint8_t f_dae:1; /* Deallocated errors supported (1.2) */ 11268d5300d3SRobert Mustacchi uint8_t f_uidreuse:1; /* GUID reuse impossible (1.3) */ 11278d5300d3SRobert Mustacchi uint8_t f_optperf:1; /* Namespace I/O opt (1.4) */ 11288d5300d3SRobert Mustacchi uint8_t f_rsvd:3; 11293d9b1a2aSHans Rosenfeld } id_nsfeat; 11303d9b1a2aSHans Rosenfeld uint8_t id_nlbaf; /* Number of LBA formats */ 11313d9b1a2aSHans Rosenfeld struct { /* Formatted LBA size */ 11323d9b1a2aSHans Rosenfeld uint8_t lba_format:4; /* LBA format */ 11333d9b1a2aSHans Rosenfeld uint8_t lba_extlba:1; /* extended LBA (includes metadata) */ 11343d9b1a2aSHans Rosenfeld uint8_t lba_rsvd:3; 11353d9b1a2aSHans Rosenfeld } id_flbas; 11363d9b1a2aSHans Rosenfeld struct { /* Metadata Capabilities */ 11373d9b1a2aSHans Rosenfeld uint8_t mc_extlba:1; /* extended LBA transfers */ 11383d9b1a2aSHans Rosenfeld uint8_t mc_separate:1; /* separate metadata transfers */ 11393d9b1a2aSHans Rosenfeld uint8_t mc_rsvd:6; 11403d9b1a2aSHans Rosenfeld } id_mc; 11413d9b1a2aSHans Rosenfeld struct { /* Data Protection Capabilities */ 11423d9b1a2aSHans Rosenfeld uint8_t dp_type1:1; /* Protection Information Type 1 */ 11433d9b1a2aSHans Rosenfeld uint8_t dp_type2:1; /* Protection Information Type 2 */ 11443d9b1a2aSHans Rosenfeld uint8_t dp_type3:1; /* Protection Information Type 3 */ 11453d9b1a2aSHans Rosenfeld uint8_t dp_first:1; /* first 8 bytes of metadata */ 11463d9b1a2aSHans Rosenfeld uint8_t dp_last:1; /* last 8 bytes of metadata */ 11473d9b1a2aSHans Rosenfeld uint8_t dp_rsvd:3; 11483d9b1a2aSHans Rosenfeld } id_dpc; 11493d9b1a2aSHans Rosenfeld struct { /* Data Protection Settings */ 11503d9b1a2aSHans Rosenfeld uint8_t dp_pinfo:3; /* Protection Information enabled */ 11513d9b1a2aSHans Rosenfeld uint8_t dp_first:1; /* first 8 bytes of metadata */ 11523d9b1a2aSHans Rosenfeld uint8_t dp_rsvd:4; 11533d9b1a2aSHans Rosenfeld } id_dps; 11543d9b1a2aSHans Rosenfeld struct { /* NS Multi-Path/Sharing Cap (1.1) */ 11553d9b1a2aSHans Rosenfeld uint8_t nm_shared:1; /* NS is shared (1.1) */ 11563d9b1a2aSHans Rosenfeld uint8_t nm_rsvd:7; 11573d9b1a2aSHans Rosenfeld } id_nmic; 11583d9b1a2aSHans Rosenfeld struct { /* Reservation Capabilities (1.1) */ 11593d9b1a2aSHans Rosenfeld uint8_t rc_persist:1; /* Persist Through Power Loss (1.1) */ 11603d9b1a2aSHans Rosenfeld uint8_t rc_wr_excl:1; /* Write Exclusive (1.1) */ 11613d9b1a2aSHans Rosenfeld uint8_t rc_excl:1; /* Exclusive Access (1.1) */ 11623d9b1a2aSHans Rosenfeld uint8_t rc_wr_excl_r:1; /* Wr Excl - Registrants Only (1.1) */ 11633d9b1a2aSHans Rosenfeld uint8_t rc_excl_r:1; /* Excl Acc - Registrants Only (1.1) */ 11643d9b1a2aSHans Rosenfeld uint8_t rc_wr_excl_a:1; /* Wr Excl - All Registrants (1.1) */ 11653d9b1a2aSHans Rosenfeld uint8_t rc_excl_a:1; /* Excl Acc - All Registrants (1.1) */ 11668d5300d3SRobert Mustacchi uint8_t rc_ign_ekey:1; /* Ignore Existing Key (1.3) */ 11673d9b1a2aSHans Rosenfeld } id_rescap; 11688d5300d3SRobert Mustacchi struct { /* Format Progress Indicator (1.2) */ 11698d5300d3SRobert Mustacchi uint8_t fpi_remp:7; /* Percent NVM Format Remaining (1.2) */ 11708d5300d3SRobert Mustacchi uint8_t fpi_sup:1; /* Supported (1.2) */ 11718d5300d3SRobert Mustacchi } id_fpi; 117248d370f1SRobert Mustacchi uint8_t id_dfleat; /* Deallocate Log. Block (1.3) */ 117348d370f1SRobert Mustacchi uint16_t id_nawun; /* Atomic Write Unit Normal (1.2) */ 117448d370f1SRobert Mustacchi uint16_t id_nawupf; /* Atomic Write Unit Power Fail (1.2) */ 117548d370f1SRobert Mustacchi uint16_t id_nacwu; /* Atomic Compare & Write Unit (1.2) */ 117648d370f1SRobert Mustacchi uint16_t id_nabsn; /* Atomic Boundary Size Normal (1.2) */ 117748d370f1SRobert Mustacchi uint16_t id_nbao; /* Atomic Boundary Offset (1.2) */ 117848d370f1SRobert Mustacchi uint16_t id_nabspf; /* Atomic Boundary Size Fail (1.2) */ 117948d370f1SRobert Mustacchi uint16_t id_noiob; /* Optimal I/O Bondary (1.3) */ 11808d5300d3SRobert Mustacchi nvme_uint128_t id_nvmcap; /* NVM Capacity */ 11818d5300d3SRobert Mustacchi uint16_t id_npwg; /* NS Pref. Write Gran. (1.4) */ 11828d5300d3SRobert Mustacchi uint16_t id_npwa; /* NS Pref. Write Align. (1.4) */ 11838d5300d3SRobert Mustacchi uint16_t id_npdg; /* NS Pref. Deallocate Gran. (1.4) */ 11848d5300d3SRobert Mustacchi uint16_t id_npda; /* NS Pref. Deallocate Align. (1.4) */ 11858d5300d3SRobert Mustacchi uint16_t id_nows; /* NS. Optimal Write Size (1.4) */ 11868d5300d3SRobert Mustacchi uint8_t id_rsvd1[92 - 74]; 11878d5300d3SRobert Mustacchi uint32_t id_anagrpid; /* ANA Group Identifier (1.4) */ 11888d5300d3SRobert Mustacchi uint8_t id_rsvd2[99 - 96]; 11898d5300d3SRobert Mustacchi struct { 11908d5300d3SRobert Mustacchi uint8_t nsa_wprot:1; /* Write Protected (1.4) */ 11918d5300d3SRobert Mustacchi uint8_t nsa_rsvd:7; 11928d5300d3SRobert Mustacchi } id_nsattr; 11938d5300d3SRobert Mustacchi uint16_t id_nvmsetid; /* NVM Set Identifier (1.4) */ 11948d5300d3SRobert Mustacchi uint16_t id_endgid; /* Endurance Group Identifier (1.4) */ 119548d370f1SRobert Mustacchi uint8_t id_nguid[16]; /* Namespace GUID (1.2) */ 11963d9b1a2aSHans Rosenfeld uint8_t id_eui64[8]; /* IEEE Extended Unique Id (1.1) */ 1197533affcbSRobert Mustacchi nvme_idns_lbaf_t id_lbaf[NVME_MAX_LBAF]; /* LBA Formats */ 11983d9b1a2aSHans Rosenfeld 11998d5300d3SRobert Mustacchi uint8_t id_rsvd3[384 - 192]; 12003d9b1a2aSHans Rosenfeld 120148d370f1SRobert Mustacchi uint8_t id_vs[4096 - 384]; /* Vendor Specific */ 12023d9b1a2aSHans Rosenfeld } nvme_identify_nsid_t; 12033d9b1a2aSHans Rosenfeld 1204153f3212SHans Rosenfeld /* NVMe Identify Namespace ID List */ 1205153f3212SHans Rosenfeld typedef struct { 1206153f3212SHans Rosenfeld /* Ordered list of Namespace IDs */ 1207153f3212SHans Rosenfeld uint32_t nl_nsid[NVME_IDENTIFY_BUFSIZE / sizeof (uint32_t)]; 1208153f3212SHans Rosenfeld } nvme_identify_nsid_list_t; 1209153f3212SHans Rosenfeld 1210153f3212SHans Rosenfeld /* NVME Identify Controller ID List */ 1211153f3212SHans Rosenfeld typedef struct { 1212153f3212SHans Rosenfeld uint16_t cl_nid; /* Number of controller entries */ 1213153f3212SHans Rosenfeld /* unique controller identifiers */ 1214153f3212SHans Rosenfeld uint16_t cl_ctlid[NVME_IDENTIFY_BUFSIZE / sizeof (uint16_t) - 1]; 1215153f3212SHans Rosenfeld } nvme_identify_ctrl_list_t; 1216153f3212SHans Rosenfeld 1217153f3212SHans Rosenfeld /* NVMe Identify Namespace Descriptor */ 1218153f3212SHans Rosenfeld typedef struct { 1219153f3212SHans Rosenfeld uint8_t nd_nidt; /* Namespace Identifier Type */ 1220153f3212SHans Rosenfeld uint8_t nd_nidl; /* Namespace Identifier Length */ 1221153f3212SHans Rosenfeld uint8_t nd_resv[2]; 1222153f3212SHans Rosenfeld uint8_t nd_nid[]; /* Namespace Identifier */ 1223153f3212SHans Rosenfeld } nvme_identify_nsid_desc_t; 1224153f3212SHans Rosenfeld 1225153f3212SHans Rosenfeld #define NVME_NSID_DESC_EUI64 1 1226153f3212SHans Rosenfeld #define NVME_NSID_DESC_NGUID 2 1227153f3212SHans Rosenfeld #define NVME_NSID_DESC_NUUID 3 1228153f3212SHans Rosenfeld #define NVME_NSID_DESC_MIN NVME_NSID_DESC_EUI64 1229153f3212SHans Rosenfeld #define NVME_NSID_DESC_MAX NVME_NSID_DESC_NUUID 1230153f3212SHans Rosenfeld 1231153f3212SHans Rosenfeld #define NVME_NSID_DESC_LEN_EUI64 8 1232153f3212SHans Rosenfeld #define NVME_NSID_DESC_LEN_NGUID 16 1233153f3212SHans Rosenfeld #define NVME_NSID_DESC_LEN_NUUID UUID_LEN 1234153f3212SHans Rosenfeld 123548d370f1SRobert Mustacchi /* NVMe Identify Primary Controller Capabilities */ 123648d370f1SRobert Mustacchi typedef struct { 123748d370f1SRobert Mustacchi uint16_t nipc_cntlid; /* Controller ID */ 123848d370f1SRobert Mustacchi uint16_t nipc_portid; /* Port Identifier */ 123948d370f1SRobert Mustacchi uint8_t nipc_crt; /* Controller Resource Types */ 124048d370f1SRobert Mustacchi uint8_t nipc_rsvd0[32 - 5]; 124148d370f1SRobert Mustacchi uint32_t nipc_vqfrt; /* VQ Resources Flexible Total */ 124248d370f1SRobert Mustacchi uint32_t nipc_vqrfa; /* VQ Resources Flexible Assigned */ 124348d370f1SRobert Mustacchi uint16_t nipc_vqrfap; /* VQ Resources to Primary */ 124448d370f1SRobert Mustacchi uint16_t nipc_vqprt; /* VQ Resources Private Total */ 124548d370f1SRobert Mustacchi uint16_t nipc_vqfrsm; /* VQ Resources Secondary Max */ 124648d370f1SRobert Mustacchi uint16_t nipc_vqgran; /* VQ Flexible Resource Gran */ 124748d370f1SRobert Mustacchi uint8_t nipc_rvsd1[64 - 48]; 124848d370f1SRobert Mustacchi uint32_t nipc_vifrt; /* VI Flexible total */ 124948d370f1SRobert Mustacchi uint32_t nipc_virfa; /* VI Flexible Assigned */ 12508d5300d3SRobert Mustacchi uint16_t nipc_virfap; /* VI Flexible Allocated to Primary */ 125148d370f1SRobert Mustacchi uint16_t nipc_viprt; /* VI Resources Private Total */ 125248d370f1SRobert Mustacchi uint16_t nipc_vifrsm; /* VI Resources Secondary Max */ 125348d370f1SRobert Mustacchi uint16_t nipc_vigran; /* VI Flexible Granularity */ 125448d370f1SRobert Mustacchi uint8_t nipc_rsvd2[4096 - 80]; 125548d370f1SRobert Mustacchi } nvme_identify_primary_caps_t; 12563d9b1a2aSHans Rosenfeld 12573d9b1a2aSHans Rosenfeld /* 12583d9b1a2aSHans Rosenfeld * NVMe completion queue entry status field 12593d9b1a2aSHans Rosenfeld */ 12603d9b1a2aSHans Rosenfeld typedef struct { 12613d9b1a2aSHans Rosenfeld uint16_t sf_p:1; /* Phase Tag */ 12623d9b1a2aSHans Rosenfeld uint16_t sf_sc:8; /* Status Code */ 12633d9b1a2aSHans Rosenfeld uint16_t sf_sct:3; /* Status Code Type */ 12643d9b1a2aSHans Rosenfeld uint16_t sf_rsvd2:2; 12653d9b1a2aSHans Rosenfeld uint16_t sf_m:1; /* More */ 12663d9b1a2aSHans Rosenfeld uint16_t sf_dnr:1; /* Do Not Retry */ 12673d9b1a2aSHans Rosenfeld } nvme_cqe_sf_t; 12683d9b1a2aSHans Rosenfeld 12693d9b1a2aSHans Rosenfeld 12703d9b1a2aSHans Rosenfeld /* 12713d9b1a2aSHans Rosenfeld * NVMe Get Log Page 12723d9b1a2aSHans Rosenfeld */ 1273533affcbSRobert Mustacchi #define NVME_LOGPAGE_SUP 0x00 /* Supported Logs (2.0) */ 1274533affcbSRobert Mustacchi #define NVME_LOGPAGE_ERROR 0x01 /* Error Information */ 1275533affcbSRobert Mustacchi #define NVME_LOGPAGE_HEALTH 0x02 /* SMART/Health Information */ 1276533affcbSRobert Mustacchi #define NVME_LOGPAGE_FWSLOT 0x03 /* Firmware Slot Information */ 1277533affcbSRobert Mustacchi #define NVME_LOGPAGE_NSCHANGE 0x04 /* Changed namespace (1.2) */ 1278533affcbSRobert Mustacchi #define NVME_LOGPAGE_CMDSUP 0x05 /* Cmds. Supported and Effects (1.3) */ 1279533affcbSRobert Mustacchi #define NVME_LOGPAGE_SELFTEST 0x06 /* Device self-test (1.3) */ 1280533affcbSRobert Mustacchi #define NVME_LOGPAGE_TELMHOST 0x07 /* Telemetry Host-Initiated */ 1281533affcbSRobert Mustacchi #define NVME_LOGPAGE_TELMCTRL 0x08 /* Telemetry Controller-Initiated */ 1282533affcbSRobert Mustacchi #define NVME_LOGPAGE_ENDGRP 0x09 /* Endurance Group Information (1.4) */ 1283533affcbSRobert Mustacchi #define NVME_LOGPAGE_PLATSET 0x0a /* Predictable Lat. per NVM Set (1.4) */ 1284533affcbSRobert Mustacchi #define NVME_LOGPAGE_PLATAGG 0x0b /* Predictable Lat. Event Agg (1.4) */ 1285533affcbSRobert Mustacchi #define NVME_LOGPAGE_ASYMNS 0x0c /* Asymmetric Namespace Access (1.4) */ 1286533affcbSRobert Mustacchi #define NVME_LOGPAGE_PEVLOG 0x0d /* Persistent Event Log (1.4) */ 1287533affcbSRobert Mustacchi #define NVME_LOGPAGE_LBASTS 0x0e /* LBA Status Information (1.4) */ 1288533affcbSRobert Mustacchi #define NVME_LOGPAGE_ENDAGG 0x0f /* Endurance Group Event Agg. (1.4) */ 1289533affcbSRobert Mustacchi 1290533affcbSRobert Mustacchi #define NVME_LOGPAGE_VEND_MIN 0xc0 1291533affcbSRobert Mustacchi #define NVME_LOGPAGE_VEND_MAX 0xff 12923d9b1a2aSHans Rosenfeld 1293*046911ebSRobert Mustacchi /* 1294*046911ebSRobert Mustacchi * Supported Log Pages (2.0). There is one entry of an nvme_logsup_t that then 1295*046911ebSRobert Mustacchi * exists on a per-log basis. 1296*046911ebSRobert Mustacchi */ 1297*046911ebSRobert Mustacchi 1298*046911ebSRobert Mustacchi /* 1299*046911ebSRobert Mustacchi * The NVMe Log Identifier specific parameter field. Currently there is only one 1300*046911ebSRobert Mustacchi * defined field for the persistent event log (pel). 1301*046911ebSRobert Mustacchi */ 1302*046911ebSRobert Mustacchi typedef union { 1303*046911ebSRobert Mustacchi uint16_t nsl_lidsp; /* Raw Value */ 1304*046911ebSRobert Mustacchi struct { /* Persistent Event Log */ 1305*046911ebSRobert Mustacchi uint16_t nsl_ec512:1; 1306*046911ebSRobert Mustacchi uint16_t nsl_pel_rsvd0p1:15; 1307*046911ebSRobert Mustacchi } nsl_pel; 1308*046911ebSRobert Mustacchi } nvme_suplog_lidsp_t; 1309*046911ebSRobert Mustacchi 1310*046911ebSRobert Mustacchi typedef struct { 1311*046911ebSRobert Mustacchi uint16_t ns_lsupp:1; 1312*046911ebSRobert Mustacchi uint16_t ns_ios:1; 1313*046911ebSRobert Mustacchi uint16_t ns_rsvd0p2:14; 1314*046911ebSRobert Mustacchi nvme_suplog_lidsp_t ns_lidsp; 1315*046911ebSRobert Mustacchi } nvme_suplog_t; 1316*046911ebSRobert Mustacchi 1317*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_suplog_lidsp_t) == 2); 1318*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_suplog_t) == 4); 1319*046911ebSRobert Mustacchi 1320*046911ebSRobert Mustacchi typedef struct { 1321*046911ebSRobert Mustacchi nvme_suplog_t nl_logs[256]; 1322*046911ebSRobert Mustacchi } nvme_suplog_log_t; 1323*046911ebSRobert Mustacchi 1324*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_suplog_log_t) == 1024); 1325*046911ebSRobert Mustacchi 1326*046911ebSRobert Mustacchi /* 1327*046911ebSRobert Mustacchi * SMART / Health information 1328*046911ebSRobert Mustacchi */ 13293d9b1a2aSHans Rosenfeld typedef struct { 13303d9b1a2aSHans Rosenfeld uint64_t el_count; /* Error Count */ 13313d9b1a2aSHans Rosenfeld uint16_t el_sqid; /* Submission Queue ID */ 13323d9b1a2aSHans Rosenfeld uint16_t el_cid; /* Command ID */ 13333d9b1a2aSHans Rosenfeld nvme_cqe_sf_t el_sf; /* Status Field */ 13343d9b1a2aSHans Rosenfeld uint8_t el_byte; /* Parameter Error Location byte */ 13353d9b1a2aSHans Rosenfeld uint8_t el_bit:3; /* Parameter Error Location bit */ 13363d9b1a2aSHans Rosenfeld uint8_t el_rsvd1:5; 13373d9b1a2aSHans Rosenfeld uint64_t el_lba; /* Logical Block Address */ 13383d9b1a2aSHans Rosenfeld uint32_t el_nsid; /* Namespace ID */ 13393d9b1a2aSHans Rosenfeld uint8_t el_vendor; /* Vendor Specific Information avail */ 13403d9b1a2aSHans Rosenfeld uint8_t el_rsvd2[64 - 29]; 13413d9b1a2aSHans Rosenfeld } nvme_error_log_entry_t; 13423d9b1a2aSHans Rosenfeld 13433d9b1a2aSHans Rosenfeld typedef struct { 13443d9b1a2aSHans Rosenfeld struct { /* Critical Warning */ 13453d9b1a2aSHans Rosenfeld uint8_t cw_avail:1; /* available space too low */ 13463d9b1a2aSHans Rosenfeld uint8_t cw_temp:1; /* temperature too high */ 13473d9b1a2aSHans Rosenfeld uint8_t cw_reliab:1; /* degraded reliability */ 13483d9b1a2aSHans Rosenfeld uint8_t cw_readonly:1; /* media is read-only */ 13493d9b1a2aSHans Rosenfeld uint8_t cw_volatile:1; /* volatile memory backup failed */ 13503d9b1a2aSHans Rosenfeld uint8_t cw_rsvd:3; 13513d9b1a2aSHans Rosenfeld } hl_crit_warn; 13523d9b1a2aSHans Rosenfeld uint16_t hl_temp; /* Temperature */ 13533d9b1a2aSHans Rosenfeld uint8_t hl_avail_spare; /* Available Spare */ 13543d9b1a2aSHans Rosenfeld uint8_t hl_avail_spare_thr; /* Available Spare Threshold */ 13553d9b1a2aSHans Rosenfeld uint8_t hl_used; /* Percentage Used */ 13563d9b1a2aSHans Rosenfeld uint8_t hl_rsvd1[32 - 6]; 13573d9b1a2aSHans Rosenfeld nvme_uint128_t hl_data_read; /* Data Units Read */ 13583d9b1a2aSHans Rosenfeld nvme_uint128_t hl_data_write; /* Data Units Written */ 13593d9b1a2aSHans Rosenfeld nvme_uint128_t hl_host_read; /* Host Read Commands */ 13603d9b1a2aSHans Rosenfeld nvme_uint128_t hl_host_write; /* Host Write Commands */ 13613d9b1a2aSHans Rosenfeld nvme_uint128_t hl_ctrl_busy; /* Controller Busy Time */ 13623d9b1a2aSHans Rosenfeld nvme_uint128_t hl_power_cycles; /* Power Cycles */ 13633d9b1a2aSHans Rosenfeld nvme_uint128_t hl_power_on_hours; /* Power On Hours */ 13643d9b1a2aSHans Rosenfeld nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */ 13653d9b1a2aSHans Rosenfeld nvme_uint128_t hl_media_errors; /* Media Errors */ 13663d9b1a2aSHans Rosenfeld nvme_uint128_t hl_errors_logged; /* Number of errors logged */ 13674a663bacSRobert Mustacchi /* Added in NVMe 1.2 */ 13684a663bacSRobert Mustacchi uint32_t hl_warn_temp_time; /* Warning Composite Temp Time */ 13694a663bacSRobert Mustacchi uint32_t hl_crit_temp_time; /* Critical Composite Temp Time */ 13704a663bacSRobert Mustacchi uint16_t hl_temp_sensor_1; /* Temperature Sensor 1 */ 13714a663bacSRobert Mustacchi uint16_t hl_temp_sensor_2; /* Temperature Sensor 2 */ 13724a663bacSRobert Mustacchi uint16_t hl_temp_sensor_3; /* Temperature Sensor 3 */ 13734a663bacSRobert Mustacchi uint16_t hl_temp_sensor_4; /* Temperature Sensor 4 */ 13744a663bacSRobert Mustacchi uint16_t hl_temp_sensor_5; /* Temperature Sensor 5 */ 13754a663bacSRobert Mustacchi uint16_t hl_temp_sensor_6; /* Temperature Sensor 6 */ 13764a663bacSRobert Mustacchi uint16_t hl_temp_sensor_7; /* Temperature Sensor 7 */ 13774a663bacSRobert Mustacchi uint16_t hl_temp_sensor_8; /* Temperature Sensor 8 */ 13784a663bacSRobert Mustacchi /* Added in NVMe 1.3 */ 13794a663bacSRobert Mustacchi uint32_t hl_tmtemp_1_tc; /* Thermal Mgmt Temp 1 Transition # */ 13804a663bacSRobert Mustacchi uint32_t hl_tmtemp_2_tc; /* Thermal Mgmt Temp 1 Transition # */ 13814a663bacSRobert Mustacchi uint32_t hl_tmtemp_1_time; /* Time in Thermal Mgmt Temp 1 */ 13824a663bacSRobert Mustacchi uint32_t hl_tmtemp_2_time; /* Time in Thermal Mgmt Temp 2 */ 13834a663bacSRobert Mustacchi uint8_t hl_rsvd2[512 - 232]; 13843d9b1a2aSHans Rosenfeld } nvme_health_log_t; 13853d9b1a2aSHans Rosenfeld 1386e89be50aSRob Johnston /* 1387e89be50aSRob Johnston * The NVMe spec allows for up to seven firmware slots. 1388e89be50aSRob Johnston */ 1389e89be50aSRob Johnston #define NVME_MAX_FWSLOTS 7 1390e89be50aSRob Johnston 13913d9b1a2aSHans Rosenfeld typedef struct { 1392e89be50aSRob Johnston /* Active Firmware Slot */ 1393e89be50aSRob Johnston uint8_t fw_afi:3; 1394cf840871SPaul Winder uint8_t fw_rsvd1:1; 1395e89be50aSRob Johnston /* Next Active Firmware Slot */ 1396e89be50aSRob Johnston uint8_t fw_next:3; 1397cf840871SPaul Winder uint8_t fw_rsvd2:1; 1398cf840871SPaul Winder uint8_t fw_rsvd3[7]; 1399e89be50aSRob Johnston /* Firmware Revision / Slot */ 1400e89be50aSRob Johnston char fw_frs[NVME_MAX_FWSLOTS][NVME_FWVER_SZ]; 1401cf840871SPaul Winder uint8_t fw_rsvd4[512 - 64]; 14023d9b1a2aSHans Rosenfeld } nvme_fwslot_log_t; 14033d9b1a2aSHans Rosenfeld 140404be5853SAndy Fiddaman /* 140504be5853SAndy Fiddaman * The NVMe spec specifies that the changed namespace list contains up to 140604be5853SAndy Fiddaman * 1024 entries. 140704be5853SAndy Fiddaman */ 140804be5853SAndy Fiddaman #define NVME_NSCHANGE_LIST_SIZE 1024 140904be5853SAndy Fiddaman 141004be5853SAndy Fiddaman typedef struct { 141104be5853SAndy Fiddaman uint32_t nscl_ns[NVME_NSCHANGE_LIST_SIZE]; 1412153f3212SHans Rosenfeld } nvme_nschange_list_t; 14133d9b1a2aSHans Rosenfeld 14143d9b1a2aSHans Rosenfeld /* 1415*046911ebSRobert Mustacchi * Commands Supported and Effects log page and information structure. This was 1416*046911ebSRobert Mustacchi * an optional log page added in NVMe 1.2. 1417*046911ebSRobert Mustacchi */ 1418*046911ebSRobert Mustacchi typedef struct { 1419*046911ebSRobert Mustacchi uint8_t cmd_csupp:1; /* Command supported */ 1420*046911ebSRobert Mustacchi uint8_t cmd_lbcc:1; /* Logical block content change */ 1421*046911ebSRobert Mustacchi uint8_t cmd_ncc:1; /* Namespace capability change */ 1422*046911ebSRobert Mustacchi uint8_t cmd_nic:1; /* Namespace inventory change */ 1423*046911ebSRobert Mustacchi uint8_t cmd_ccc:1; /* Controller capability change */ 1424*046911ebSRobert Mustacchi uint8_t cmd_rsvd0p5:3; 1425*046911ebSRobert Mustacchi uint8_t cmd_rsvd1; 1426*046911ebSRobert Mustacchi uint16_t cmd_cse:3; /* Command submission and execution */ 1427*046911ebSRobert Mustacchi uint16_t cmd_uuid:1; /* UUID select supported, 1.4 */ 1428*046911ebSRobert Mustacchi uint16_t cmd_csp:12; /* Command Scope, 2.0 */ 1429*046911ebSRobert Mustacchi } nvme_cmdeff_t; 1430*046911ebSRobert Mustacchi 1431*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_cmdeff_t) == 4); 1432*046911ebSRobert Mustacchi 1433*046911ebSRobert Mustacchi typedef enum { 1434*046911ebSRobert Mustacchi NVME_CMDEFF_CSP_NS = 1 << 0, 1435*046911ebSRobert Mustacchi NVME_CMDEFF_CSP_CTRL = 1 << 1, 1436*046911ebSRobert Mustacchi NVME_CMDEFF_CSP_SET = 1 << 2, 1437*046911ebSRobert Mustacchi NVME_CMDEFF_CSP_ENDURANCE = 1 << 3, 1438*046911ebSRobert Mustacchi NVME_CMDEFF_CSP_DOMAIN = 1 << 4, 1439*046911ebSRobert Mustacchi NVME_CMDEFF_CSP_NVM = 1 << 5 1440*046911ebSRobert Mustacchi } nvme_cmdeff_csp_t; 1441*046911ebSRobert Mustacchi 1442*046911ebSRobert Mustacchi typedef enum { 1443*046911ebSRobert Mustacchi NVME_CMDEFF_CSE_NONE = 0, 1444*046911ebSRobert Mustacchi NVME_CMDEFF_CSE_NS, 1445*046911ebSRobert Mustacchi NVME_CMDEFF_CSE_CTRL 1446*046911ebSRobert Mustacchi } nvme_cmdeff_cse_t; 1447*046911ebSRobert Mustacchi 1448*046911ebSRobert Mustacchi typedef struct { 1449*046911ebSRobert Mustacchi nvme_cmdeff_t cme_admin[256]; 1450*046911ebSRobert Mustacchi nvme_cmdeff_t cme_io[256]; 1451*046911ebSRobert Mustacchi uint8_t cme_rsvd2048[2048]; 1452*046911ebSRobert Mustacchi } nvme_cmdeff_log_t; 1453*046911ebSRobert Mustacchi 1454*046911ebSRobert Mustacchi CTASSERT(sizeof (nvme_cmdeff_log_t) == 4096); 1455*046911ebSRobert Mustacchi CTASSERT(offsetof(nvme_cmdeff_log_t, cme_rsvd2048) == 2048); 1456*046911ebSRobert Mustacchi 1457*046911ebSRobert Mustacchi /* 14583d9b1a2aSHans Rosenfeld * NVMe Format NVM 14593d9b1a2aSHans Rosenfeld */ 14603d9b1a2aSHans Rosenfeld #define NVME_FRMT_SES_NONE 0 14613d9b1a2aSHans Rosenfeld #define NVME_FRMT_SES_USER 1 14623d9b1a2aSHans Rosenfeld #define NVME_FRMT_SES_CRYPTO 2 14633d9b1a2aSHans Rosenfeld #define NVME_FRMT_MAX_SES 2 14643d9b1a2aSHans Rosenfeld 14653d9b1a2aSHans Rosenfeld #define NVME_FRMT_MAX_LBAF 15 14663d9b1a2aSHans Rosenfeld 14673d9b1a2aSHans Rosenfeld typedef union { 14683d9b1a2aSHans Rosenfeld struct { 14693d9b1a2aSHans Rosenfeld uint32_t fm_lbaf:4; /* LBA Format */ 14703d9b1a2aSHans Rosenfeld uint32_t fm_ms:1; /* Metadata Settings */ 14713d9b1a2aSHans Rosenfeld uint32_t fm_pi:3; /* Protection Information */ 14723d9b1a2aSHans Rosenfeld uint32_t fm_pil:1; /* Prot. Information Location */ 14733d9b1a2aSHans Rosenfeld uint32_t fm_ses:3; /* Secure Erase Settings */ 14743d9b1a2aSHans Rosenfeld uint32_t fm_resvd:20; 14753d9b1a2aSHans Rosenfeld } b; 14763d9b1a2aSHans Rosenfeld uint32_t r; 14773d9b1a2aSHans Rosenfeld } nvme_format_nvm_t; 14783d9b1a2aSHans Rosenfeld 14793d9b1a2aSHans Rosenfeld 14803d9b1a2aSHans Rosenfeld /* 14813d9b1a2aSHans Rosenfeld * NVMe Get / Set Features 14823d9b1a2aSHans Rosenfeld */ 14833d9b1a2aSHans Rosenfeld #define NVME_FEAT_ARBITRATION 0x1 /* Command Arbitration */ 14843d9b1a2aSHans Rosenfeld #define NVME_FEAT_POWER_MGMT 0x2 /* Power Management */ 14853d9b1a2aSHans Rosenfeld #define NVME_FEAT_LBA_RANGE 0x3 /* LBA Range Type */ 14863d9b1a2aSHans Rosenfeld #define NVME_FEAT_TEMPERATURE 0x4 /* Temperature Threshold */ 14873d9b1a2aSHans Rosenfeld #define NVME_FEAT_ERROR 0x5 /* Error Recovery */ 14883d9b1a2aSHans Rosenfeld #define NVME_FEAT_WRITE_CACHE 0x6 /* Volatile Write Cache */ 14893d9b1a2aSHans Rosenfeld #define NVME_FEAT_NQUEUES 0x7 /* Number of Queues */ 14903d9b1a2aSHans Rosenfeld #define NVME_FEAT_INTR_COAL 0x8 /* Interrupt Coalescing */ 14913d9b1a2aSHans Rosenfeld #define NVME_FEAT_INTR_VECT 0x9 /* Interrupt Vector Configuration */ 14923d9b1a2aSHans Rosenfeld #define NVME_FEAT_WRITE_ATOM 0xa /* Write Atomicity */ 14933d9b1a2aSHans Rosenfeld #define NVME_FEAT_ASYNC_EVENT 0xb /* Asynchronous Event Configuration */ 14943d9b1a2aSHans Rosenfeld #define NVME_FEAT_AUTO_PST 0xc /* Autonomous Power State Transition */ 14953d9b1a2aSHans Rosenfeld /* (1.1) */ 14963d9b1a2aSHans Rosenfeld 14973d9b1a2aSHans Rosenfeld #define NVME_FEAT_PROGRESS 0x80 /* Software Progress Marker */ 14983d9b1a2aSHans Rosenfeld 1499533affcbSRobert Mustacchi /* 1500533affcbSRobert Mustacchi * This enumeration represents the capabilities in the Get Features select / Set 1501533affcbSRobert Mustacchi * Features save options. This was introduced in NVMe 1.1 and the values below 1502533affcbSRobert Mustacchi * match the specification. An optional feature in the identify controller data 1503533affcbSRobert Mustacchi * structure is set to indicate that this is supported (id_oncs.on_save). 1504533affcbSRobert Mustacchi */ 1505533affcbSRobert Mustacchi typedef enum { 1506533affcbSRobert Mustacchi NVME_FEATURE_SEL_CURRENT = 0, 1507533affcbSRobert Mustacchi NVME_FEATURE_SEL_DEFAULT, 1508533affcbSRobert Mustacchi NVME_FEATURE_SEL_SAVED, 1509533affcbSRobert Mustacchi NVME_FEATURE_SEL_SUPPORTED 1510533affcbSRobert Mustacchi } nvme_feature_sel_t; 1511533affcbSRobert Mustacchi 1512533affcbSRobert Mustacchi typedef union { 1513533affcbSRobert Mustacchi struct { 1514533affcbSRobert Mustacchi uint32_t gt_fid:8; /* Feature ID */ 1515533affcbSRobert Mustacchi uint32_t gt_sel:3; /* Select */ 1516533affcbSRobert Mustacchi uint32_t gt_rsvd:21; 1517533affcbSRobert Mustacchi } b; 1518533affcbSRobert Mustacchi uint32_t r; 1519533affcbSRobert Mustacchi } nvme_get_features_dw10_t; 1520533affcbSRobert Mustacchi 15213d9b1a2aSHans Rosenfeld /* Arbitration Feature */ 15223d9b1a2aSHans Rosenfeld typedef union { 15233d9b1a2aSHans Rosenfeld struct { 15243d9b1a2aSHans Rosenfeld uint8_t arb_ab:3; /* Arbitration Burst */ 15253d9b1a2aSHans Rosenfeld uint8_t arb_rsvd:5; 15263d9b1a2aSHans Rosenfeld uint8_t arb_lpw; /* Low Priority Weight */ 15273d9b1a2aSHans Rosenfeld uint8_t arb_mpw; /* Medium Priority Weight */ 15283d9b1a2aSHans Rosenfeld uint8_t arb_hpw; /* High Priority Weight */ 15293d9b1a2aSHans Rosenfeld } b; 15303d9b1a2aSHans Rosenfeld uint32_t r; 15313d9b1a2aSHans Rosenfeld } nvme_arbitration_t; 15323d9b1a2aSHans Rosenfeld 15333d9b1a2aSHans Rosenfeld /* Power Management Feature */ 15343d9b1a2aSHans Rosenfeld typedef union { 15353d9b1a2aSHans Rosenfeld struct { 15363d9b1a2aSHans Rosenfeld uint32_t pm_ps:5; /* Power State */ 15373d9b1a2aSHans Rosenfeld uint32_t pm_rsvd:27; 15383d9b1a2aSHans Rosenfeld } b; 15393d9b1a2aSHans Rosenfeld uint32_t r; 15403d9b1a2aSHans Rosenfeld } nvme_power_mgmt_t; 15413d9b1a2aSHans Rosenfeld 15423d9b1a2aSHans Rosenfeld /* LBA Range Type Feature */ 15433d9b1a2aSHans Rosenfeld typedef union { 15443d9b1a2aSHans Rosenfeld struct { 15453d9b1a2aSHans Rosenfeld uint32_t lr_num:6; /* Number of LBA ranges */ 15463d9b1a2aSHans Rosenfeld uint32_t lr_rsvd:26; 15473d9b1a2aSHans Rosenfeld } b; 15483d9b1a2aSHans Rosenfeld uint32_t r; 15493d9b1a2aSHans Rosenfeld } nvme_lba_range_type_t; 15503d9b1a2aSHans Rosenfeld 15513d9b1a2aSHans Rosenfeld typedef struct { 15523d9b1a2aSHans Rosenfeld uint8_t lr_type; /* Type */ 15533d9b1a2aSHans Rosenfeld struct { /* Attributes */ 15543d9b1a2aSHans Rosenfeld uint8_t lr_write:1; /* may be overwritten */ 15553d9b1a2aSHans Rosenfeld uint8_t lr_hidden:1; /* hidden from OS/EFI/BIOS */ 15563d9b1a2aSHans Rosenfeld uint8_t lr_rsvd1:6; 15573d9b1a2aSHans Rosenfeld } lr_attr; 15583d9b1a2aSHans Rosenfeld uint8_t lr_rsvd2[14]; 15593d9b1a2aSHans Rosenfeld uint64_t lr_slba; /* Starting LBA */ 15603d9b1a2aSHans Rosenfeld uint64_t lr_nlb; /* Number of Logical Blocks */ 15613d9b1a2aSHans Rosenfeld uint8_t lr_guid[16]; /* Unique Identifier */ 15623d9b1a2aSHans Rosenfeld uint8_t lr_rsvd3[16]; 15633d9b1a2aSHans Rosenfeld } nvme_lba_range_t; 15643d9b1a2aSHans Rosenfeld 15653d9b1a2aSHans Rosenfeld #define NVME_LBA_RANGE_BUFSIZE 4096 15663d9b1a2aSHans Rosenfeld 15673d9b1a2aSHans Rosenfeld /* Temperature Threshold Feature */ 15683d9b1a2aSHans Rosenfeld typedef union { 15693d9b1a2aSHans Rosenfeld struct { 15703d9b1a2aSHans Rosenfeld uint16_t tt_tmpth; /* Temperature Threshold */ 15714a663bacSRobert Mustacchi uint16_t tt_tmpsel:4; /* Temperature Select */ 15724a663bacSRobert Mustacchi uint16_t tt_thsel:2; /* Temperature Type */ 15734a663bacSRobert Mustacchi uint16_t tt_resv:10; 15743d9b1a2aSHans Rosenfeld } b; 15753d9b1a2aSHans Rosenfeld uint32_t r; 15763d9b1a2aSHans Rosenfeld } nvme_temp_threshold_t; 15773d9b1a2aSHans Rosenfeld 15784a663bacSRobert Mustacchi #define NVME_TEMP_THRESH_MAX_SENSOR 8 15794a663bacSRobert Mustacchi #define NVME_TEMP_THRESH_ALL 0xf 15804a663bacSRobert Mustacchi #define NVME_TEMP_THRESH_OVER 0x00 15814a663bacSRobert Mustacchi #define NVME_TEMP_THRESH_UNDER 0x01 15824a663bacSRobert Mustacchi 15833d9b1a2aSHans Rosenfeld /* Error Recovery Feature */ 15843d9b1a2aSHans Rosenfeld typedef union { 15853d9b1a2aSHans Rosenfeld struct { 15863d9b1a2aSHans Rosenfeld uint16_t er_tler; /* Time-Limited Error Recovery */ 15873d9b1a2aSHans Rosenfeld uint16_t er_rsvd; 15883d9b1a2aSHans Rosenfeld } b; 15893d9b1a2aSHans Rosenfeld uint32_t r; 15903d9b1a2aSHans Rosenfeld } nvme_error_recovery_t; 15913d9b1a2aSHans Rosenfeld 15923d9b1a2aSHans Rosenfeld /* Volatile Write Cache Feature */ 15933d9b1a2aSHans Rosenfeld typedef union { 15943d9b1a2aSHans Rosenfeld struct { 15953d9b1a2aSHans Rosenfeld uint32_t wc_wce:1; /* Volatile Write Cache Enable */ 15963d9b1a2aSHans Rosenfeld uint32_t wc_rsvd:31; 15973d9b1a2aSHans Rosenfeld } b; 15983d9b1a2aSHans Rosenfeld uint32_t r; 15993d9b1a2aSHans Rosenfeld } nvme_write_cache_t; 16003d9b1a2aSHans Rosenfeld 16013d9b1a2aSHans Rosenfeld /* Number of Queues Feature */ 16023d9b1a2aSHans Rosenfeld typedef union { 16033d9b1a2aSHans Rosenfeld struct { 16043d9b1a2aSHans Rosenfeld uint16_t nq_nsq; /* Number of Submission Queues */ 16053d9b1a2aSHans Rosenfeld uint16_t nq_ncq; /* Number of Completion Queues */ 16063d9b1a2aSHans Rosenfeld } b; 16073d9b1a2aSHans Rosenfeld uint32_t r; 16083d9b1a2aSHans Rosenfeld } nvme_nqueues_t; 16093d9b1a2aSHans Rosenfeld 16103d9b1a2aSHans Rosenfeld /* Interrupt Coalescing Feature */ 16113d9b1a2aSHans Rosenfeld typedef union { 16123d9b1a2aSHans Rosenfeld struct { 16133d9b1a2aSHans Rosenfeld uint8_t ic_thr; /* Aggregation Threshold */ 16143d9b1a2aSHans Rosenfeld uint8_t ic_time; /* Aggregation Time */ 16153d9b1a2aSHans Rosenfeld uint16_t ic_rsvd; 16163d9b1a2aSHans Rosenfeld } b; 16173d9b1a2aSHans Rosenfeld uint32_t r; 16183d9b1a2aSHans Rosenfeld } nvme_intr_coal_t; 16193d9b1a2aSHans Rosenfeld 16203d9b1a2aSHans Rosenfeld /* Interrupt Configuration Features */ 16213d9b1a2aSHans Rosenfeld typedef union { 16223d9b1a2aSHans Rosenfeld struct { 16233d9b1a2aSHans Rosenfeld uint16_t iv_iv; /* Interrupt Vector */ 16243d9b1a2aSHans Rosenfeld uint16_t iv_cd:1; /* Coalescing Disable */ 16253d9b1a2aSHans Rosenfeld uint16_t iv_rsvd:15; 16263d9b1a2aSHans Rosenfeld } b; 16273d9b1a2aSHans Rosenfeld uint32_t r; 16283d9b1a2aSHans Rosenfeld } nvme_intr_vect_t; 16293d9b1a2aSHans Rosenfeld 16303d9b1a2aSHans Rosenfeld /* Write Atomicity Feature */ 16313d9b1a2aSHans Rosenfeld typedef union { 16323d9b1a2aSHans Rosenfeld struct { 16333d9b1a2aSHans Rosenfeld uint32_t wa_dn:1; /* Disable Normal */ 16343d9b1a2aSHans Rosenfeld uint32_t wa_rsvd:31; 16353d9b1a2aSHans Rosenfeld } b; 16363d9b1a2aSHans Rosenfeld uint32_t r; 16373d9b1a2aSHans Rosenfeld } nvme_write_atomicity_t; 16383d9b1a2aSHans Rosenfeld 16393d9b1a2aSHans Rosenfeld /* Asynchronous Event Configuration Feature */ 16403d9b1a2aSHans Rosenfeld typedef union { 16413d9b1a2aSHans Rosenfeld struct { 164204be5853SAndy Fiddaman uint8_t aec_avail:1; /* Available space too low */ 164304be5853SAndy Fiddaman uint8_t aec_temp:1; /* Temperature too high */ 164404be5853SAndy Fiddaman uint8_t aec_reliab:1; /* Degraded reliability */ 164504be5853SAndy Fiddaman uint8_t aec_readonly:1; /* Media is read-only */ 164604be5853SAndy Fiddaman uint8_t aec_volatile:1; /* Volatile memory backup failed */ 16473d9b1a2aSHans Rosenfeld uint8_t aec_rsvd1:3; 164804be5853SAndy Fiddaman uint8_t aec_nsan:1; /* Namespace attribute notices (1.2) */ 164904be5853SAndy Fiddaman uint8_t aec_fwact:1; /* Firmware activation notices (1.2) */ 165004be5853SAndy Fiddaman uint8_t aec_telln:1; /* Telemetry log notices (1.3) */ 165104be5853SAndy Fiddaman uint8_t aec_ansacn:1; /* Asymm. NS access change (1.4) */ 165204be5853SAndy Fiddaman uint8_t aec_plat:1; /* Predictable latency ev. agg. (1.4) */ 165304be5853SAndy Fiddaman uint8_t aec_lbasi:1; /* LBA status information (1.4) */ 165404be5853SAndy Fiddaman uint8_t aec_egeal:1; /* Endurance group ev. agg. (1.4) */ 165504be5853SAndy Fiddaman uint8_t aec_rsvd2:1; 165604be5853SAndy Fiddaman uint8_t aec_rsvd3[2]; 16573d9b1a2aSHans Rosenfeld } b; 16583d9b1a2aSHans Rosenfeld uint32_t r; 16593d9b1a2aSHans Rosenfeld } nvme_async_event_conf_t; 16603d9b1a2aSHans Rosenfeld 16613d9b1a2aSHans Rosenfeld /* Autonomous Power State Transition Feature (1.1) */ 16623d9b1a2aSHans Rosenfeld typedef union { 16633d9b1a2aSHans Rosenfeld struct { 1664533affcbSRobert Mustacchi uint32_t apst_apste:1; /* APST enabled */ 1665533affcbSRobert Mustacchi uint32_t apst_rsvd:31; 16663d9b1a2aSHans Rosenfeld } b; 1667533affcbSRobert Mustacchi uint32_t r; 16683d9b1a2aSHans Rosenfeld } nvme_auto_power_state_trans_t; 16693d9b1a2aSHans Rosenfeld 16703d9b1a2aSHans Rosenfeld typedef struct { 16713d9b1a2aSHans Rosenfeld uint32_t apst_rsvd1:3; 16723d9b1a2aSHans Rosenfeld uint32_t apst_itps:5; /* Idle Transition Power State */ 16733d9b1a2aSHans Rosenfeld uint32_t apst_itpt:24; /* Idle Time Prior to Transition */ 16743d9b1a2aSHans Rosenfeld uint32_t apst_rsvd2; 16753d9b1a2aSHans Rosenfeld } nvme_auto_power_state_t; 16763d9b1a2aSHans Rosenfeld 16773d9b1a2aSHans Rosenfeld #define NVME_AUTO_PST_BUFSIZE 256 16783d9b1a2aSHans Rosenfeld 16793d9b1a2aSHans Rosenfeld /* Software Progress Marker Feature */ 16803d9b1a2aSHans Rosenfeld typedef union { 16813d9b1a2aSHans Rosenfeld struct { 16823d9b1a2aSHans Rosenfeld uint8_t spm_pbslc; /* Pre-Boot Software Load Count */ 16833d9b1a2aSHans Rosenfeld uint8_t spm_rsvd[3]; 16843d9b1a2aSHans Rosenfeld } b; 16853d9b1a2aSHans Rosenfeld uint32_t r; 16863d9b1a2aSHans Rosenfeld } nvme_software_progress_marker_t; 16873d9b1a2aSHans Rosenfeld 1688cf840871SPaul Winder /* 1689cf840871SPaul Winder * Firmware Commit - Command Dword 10 1690cf840871SPaul Winder */ 1691cf840871SPaul Winder #define NVME_FWC_SAVE 0x0 /* Save image only */ 1692cf840871SPaul Winder #define NVME_FWC_SAVE_ACTIVATE 0x1 /* Save and activate at next reset */ 1693cf840871SPaul Winder #define NVME_FWC_ACTIVATE 0x2 /* Activate slot at next reset */ 1694cf840871SPaul Winder #define NVME_FWC_ACTIVATE_IMMED 0x3 /* Activate slot immediately */ 1695cf840871SPaul Winder 1696cf840871SPaul Winder /* 1697cf840871SPaul Winder * Firmware slot number is only 3 bits, and zero is not allowed. 1698cf840871SPaul Winder * Valid range is 1 to 7. 1699cf840871SPaul Winder */ 1700533affcbSRobert Mustacchi #define NVME_FW_SLOT_MIN 1U /* lowest allowable slot number ... */ 1701533affcbSRobert Mustacchi #define NVME_FW_SLOT_MAX 7U /* ... and highest */ 1702cf840871SPaul Winder 1703cf840871SPaul Winder /* 1704cf840871SPaul Winder * Some constants to make verification of DWORD variables and arguments easier. 1705cf840871SPaul Winder * A DWORD is 4 bytes. 1706cf840871SPaul Winder */ 1707cf840871SPaul Winder #define NVME_DWORD_SHIFT 2 1708cf840871SPaul Winder #define NVME_DWORD_SIZE (1 << NVME_DWORD_SHIFT) 1709cf840871SPaul Winder #define NVME_DWORD_MASK (NVME_DWORD_SIZE - 1) 1710cf840871SPaul Winder 1711cf840871SPaul Winder /* 1712cf840871SPaul Winder * Maximum offset a firmware image can be load at is the number of 1713cf840871SPaul Winder * DWORDS in a 32 bit field. Expressed in bytes its is: 1714cf840871SPaul Winder */ 1715cf840871SPaul Winder #define NVME_FW_OFFSETB_MAX ((u_longlong_t)UINT32_MAX << NVME_DWORD_SHIFT) 1716cf840871SPaul Winder 1717cf840871SPaul Winder typedef union { 1718cf840871SPaul Winder struct { 1719cf840871SPaul Winder uint32_t fc_slot:3; /* Firmware slot */ 1720cf840871SPaul Winder uint32_t fc_action:3; /* Commit action */ 1721cf840871SPaul Winder uint32_t fc_rsvd:26; 1722cf840871SPaul Winder } b; 1723cf840871SPaul Winder uint32_t r; 1724cf840871SPaul Winder } nvme_firmware_commit_dw10_t; 1725cf840871SPaul Winder 17263d9b1a2aSHans Rosenfeld #pragma pack() /* pack(1) */ 17273d9b1a2aSHans Rosenfeld 1728cf840871SPaul Winder /* NVMe completion status code type */ 1729cf840871SPaul Winder #define NVME_CQE_SCT_GENERIC 0 /* Generic Command Status */ 1730cf840871SPaul Winder #define NVME_CQE_SCT_SPECIFIC 1 /* Command Specific Status */ 1731cf840871SPaul Winder #define NVME_CQE_SCT_INTEGRITY 2 /* Media and Data Integrity Errors */ 1732e7efdd31SRobert Mustacchi #define NVME_CQE_SCT_PATH 3 /* Path Related Status (1.4) */ 1733cf840871SPaul Winder #define NVME_CQE_SCT_VENDOR 7 /* Vendor Specific */ 1734cf840871SPaul Winder 1735533affcbSRobert Mustacchi /* 1736533affcbSRobert Mustacchi * Status code ranges 1737533affcbSRobert Mustacchi */ 1738533affcbSRobert Mustacchi #define NVME_CQE_SC_GEN_MIN 0x00 1739533affcbSRobert Mustacchi #define NVME_CQE_SC_GEN_MAX 0x7f 1740533affcbSRobert Mustacchi #define NVME_CQE_SC_CSI_MIN 0x80 1741533affcbSRobert Mustacchi #define NVME_CQE_SC_CSI_MAX 0xbf 1742533affcbSRobert Mustacchi #define NVME_CQE_SC_VEND_MIN 0xc0 1743533affcbSRobert Mustacchi #define NVME_CQE_SC_VEND_MAX 0xff 1744533affcbSRobert Mustacchi 1745cf840871SPaul Winder /* NVMe completion status code (generic) */ 1746cf840871SPaul Winder #define NVME_CQE_SC_GEN_SUCCESS 0x0 /* Successful Completion */ 1747cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_OPC 0x1 /* Invalid Command Opcode */ 1748cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_FLD 0x2 /* Invalid Field in Command */ 1749cf840871SPaul Winder #define NVME_CQE_SC_GEN_ID_CNFL 0x3 /* Command ID Conflict */ 1750cf840871SPaul Winder #define NVME_CQE_SC_GEN_DATA_XFR_ERR 0x4 /* Data Transfer Error */ 1751cf840871SPaul Winder #define NVME_CQE_SC_GEN_ABORT_PWRLOSS 0x5 /* Cmds Aborted / Pwr Loss */ 1752cf840871SPaul Winder #define NVME_CQE_SC_GEN_INTERNAL_ERR 0x6 /* Internal Error */ 1753cf840871SPaul Winder #define NVME_CQE_SC_GEN_ABORT_REQUEST 0x7 /* Command Abort Requested */ 1754cf840871SPaul Winder #define NVME_CQE_SC_GEN_ABORT_SQ_DEL 0x8 /* Cmd Aborted / SQ deletion */ 1755cf840871SPaul Winder #define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9 /* Cmd Aborted / Failed Fused */ 1756cf840871SPaul Winder #define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa /* Cmd Aborted / Missing Fusd */ 1757cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_NS 0xb /* Inval Namespace or Format */ 1758cf840871SPaul Winder #define NVME_CQE_SC_GEN_CMD_SEQ_ERR 0xc /* Command Sequence Error */ 1759cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_SGL_LAST 0xd /* Inval SGL Last Seg Desc */ 1760cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_SGL_NUM 0xe /* Inval Number of SGL Desc */ 1761cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_DSGL_LEN 0xf /* Data SGL Length Invalid */ 1762cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_MSGL_LEN 0x10 /* Metadata SGL Length Inval */ 1763cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_SGL_DESC 0x11 /* SGL Descriptor Type Inval */ 1764e7efdd31SRobert Mustacchi /* Added in NVMe 1.2 */ 1765cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_USE_CMB 0x12 /* Inval use of Ctrl Mem Buf */ 1766cf840871SPaul Winder #define NVME_CQE_SC_GEN_INV_PRP_OFF 0x13 /* PRP Offset Invalid */ 1767cf840871SPaul Winder #define NVME_CQE_SC_GEN_AWU_EXCEEDED 0x14 /* Atomic Write Unit Exceeded */ 1768e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_OP_DENIED 0x15 /* Operation Denied */ 1769e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_INV_SGL_OFF 0x16 /* SGL Offset Invalid */ 1770e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_INV_SGL_ST 0x17 /* SGL Sub type Invalid */ 1771e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_INCON_HOSTID 0x18 /* Host ID Inconsistent fmt */ 1772e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_KA_EXP 0x19 /* Keep Alive Timer Expired */ 1773e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_INV_KA_TO 0x1a /* Keep Alive Timeout Invalid */ 1774e7efdd31SRobert Mustacchi /* Added in NVMe 1.3 */ 1775e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_ABORT_PREEMPT 0x1b /* Cmd aborted due to preempt */ 1776e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_SANITIZE_FAIL 0x1c /* Sanitize Failed */ 1777e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_SANITIZING 0x1d /* Sanitize in Progress */ 1778e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_INV_SGL_GRAN 0x1e /* SGL Data Block Gran. Inval */ 1779e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_NO_CMD_Q_CMD 0x1f /* Command not sup for CMB Q */ 1780e7efdd31SRobert Mustacchi /* Added in NVMe 1.4 */ 1781e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_NS_RDONLY 0x20 /* Namespace is write prot. */ 1782e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_CMD_INTR 0x21 /* Command Interrupted */ 1783e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_TRANSIENT 0x22 /* Transient Transport Error */ 1784e7efdd31SRobert Mustacchi /* Added in NVMe 2.0 */ 1785e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_CMD_LOCK 0x23 /* Command/Feature Lockdown */ 1786e7efdd31SRobert Mustacchi #define NVME_CQE_SC_ADM_MEDIA_NR 0x24 /* Admin Cmd Media Not Ready */ 1787cf840871SPaul Winder 1788cf840871SPaul Winder /* NVMe completion status code (generic NVM commands) */ 1789cf840871SPaul Winder #define NVME_CQE_SC_GEN_NVM_LBA_RANGE 0x80 /* LBA Out Of Range */ 1790cf840871SPaul Winder #define NVME_CQE_SC_GEN_NVM_CAP_EXC 0x81 /* Capacity Exceeded */ 1791cf840871SPaul Winder #define NVME_CQE_SC_GEN_NVM_NS_NOTRDY 0x82 /* Namespace Not Ready */ 1792cf840871SPaul Winder #define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT 0x83 /* Reservation Conflict */ 17933eaaeb3dSAndy Fiddaman #define NVME_CQE_SC_GEN_NVM_FORMATTING 0x84 /* Format in progress (1.2) */ 1794e7efdd31SRobert Mustacchi /* Added in NVMe 2.0 */ 1795e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_KEY_INV_VAL 0x85 /* Invalid value size */ 1796e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_KEY_INV_KEY 0x86 /* Invalid key size */ 1797e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_KEY_ENOENT 0x87 /* KV Key Does Not Exist */ 1798e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_KEY_UNRECOV 0x88 /* Unrecovered Error */ 1799e7efdd31SRobert Mustacchi #define NVME_CQE_SC_GEN_KEY_EXISTS 0x89 /* Key already exists */ 1800cf840871SPaul Winder 1801cf840871SPaul Winder /* NVMe completion status code (command specific) */ 1802cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_CQ 0x0 /* Completion Queue Invalid */ 1803cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_QID 0x1 /* Invalid Queue Identifier */ 1804cf840871SPaul Winder #define NVME_CQE_SC_SPC_MAX_QSZ_EXC 0x2 /* Max Queue Size Exceeded */ 1805cf840871SPaul Winder #define NVME_CQE_SC_SPC_ABRT_CMD_EXC 0x3 /* Abort Cmd Limit Exceeded */ 1806cf840871SPaul Winder #define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5 /* Async Event Request Limit */ 1807cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_FW_SLOT 0x6 /* Invalid Firmware Slot */ 1808cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_FW_IMG 0x7 /* Invalid Firmware Image */ 1809cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_INT_VECT 0x8 /* Invalid Interrupt Vector */ 1810cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_LOG_PAGE 0x9 /* Invalid Log Page */ 1811cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_FORMAT 0xa /* Invalid Format */ 1812cf840871SPaul Winder #define NVME_CQE_SC_SPC_FW_RESET 0xb /* FW Application Reset Reqd */ 1813cf840871SPaul Winder #define NVME_CQE_SC_SPC_INV_Q_DEL 0xc /* Invalid Queue Deletion */ 1814cf840871SPaul Winder #define NVME_CQE_SC_SPC_FEAT_SAVE 0xd /* Feature Id Not Saveable */ 1815cf840871SPaul Winder #define NVME_CQE_SC_SPC_FEAT_CHG 0xe /* Feature Not Changeable */ 1816cf840871SPaul Winder #define NVME_CQE_SC_SPC_FEAT_NS_SPEC 0xf /* Feature Not Namespace Spec */ 1817e7efdd31SRobert Mustacchi /* Added in NVMe 1.2 */ 1818cf840871SPaul Winder #define NVME_CQE_SC_SPC_FW_NSSR 0x10 /* FW Application NSSR Reqd */ 1819cf840871SPaul Winder #define NVME_CQE_SC_SPC_FW_NEXT_RESET 0x11 /* FW Application Next Reqd */ 1820cf840871SPaul Winder #define NVME_CQE_SC_SPC_FW_MTFA 0x12 /* FW Application Exceed MTFA */ 1821cf840871SPaul Winder #define NVME_CQE_SC_SPC_FW_PROHIBITED 0x13 /* FW Application Prohibited */ 1822cf840871SPaul Winder #define NVME_CQE_SC_SPC_FW_OVERLAP 0x14 /* Overlapping FW ranges */ 1823e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NS_INSUF_CAP 0x15 /* NS Insufficient Capacity */ 1824e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NS_NO_ID 0x16 /* NS ID Unavailable */ 1825e7efdd31SRobert Mustacchi /* 0x17 is reserved */ 1826e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NS_ATTACHED 0x18 /* NS Already Attached */ 1827e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NS_PRIV 0x19 /* NS is private */ 1828e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NS_NOT_ATTACH 0x1a /* NS Not Attached */ 1829e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_THIN_ENOTSUP 0x1b /* Thin Provisioning ENOTSUP */ 1830e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_CTRL_LIST 0x1c /* Controller list invalid */ 1831e7efdd31SRobert Mustacchi /* Added in NVMe 1.3 */ 1832e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_SELF_TESTING 0x1d /* Self-test in progress */ 1833e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NO_BP_WRITE 0x1e /* No Boot Partition Write */ 1834e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_CTRL_ID 0x1f /* Invalid Controller Id */ 1835e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_SEC_CTRL 0x20 /* Invalid Sec. Ctrl state */ 1836e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_CTRL_NRSRC 0x21 /* Inv. # Ctrl Resources */ 1837e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_RSRC_ID 0x22 /* Inv. Resource ID */ 1838e7efdd31SRobert Mustacchi /* Added in NVMe 1.4 */ 1839e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NO_SAN_PMR 0x23 /* Sanitize prohib. w/ pmem */ 1840e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_ANA_GID 0x24 /* Invalid ANA group ID */ 1841e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ANA_ATTACH 0x25 /* ANA Attach Failed */ 1842e7efdd31SRobert Mustacchi /* Added in NVMe 2.0 */ 1843e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INSUF_CAP 0x26 /* Insufficient Capacity */ 1844e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_NS_ATTACH_LIM 0x27 /* NS Attach Limit Exceeded */ 1845e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_LOCKDOWN_UNSUP 0x28 /* Prohib Cmd Exec Not Sup */ 1846e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_UNSUP_IO_CMD 0x29 /* I/O Command set not sup */ 1847e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_DIS_IO_CMD 0x2a /* I/O Command set not enab */ 1848e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_CMD_COMBO 0x2b /* I/O command set combo rej */ 1849e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_IO_CMD 0x2c /* Invalid I/O command set */ 1850e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_UNAVAIL_ID 0x2d /* Unavailable ID */ 1851cf840871SPaul Winder 1852e7efdd31SRobert Mustacchi 1853e7efdd31SRobert Mustacchi /* NVMe completion status code (I/O command specific) */ 1854cf840871SPaul Winder #define NVME_CQE_SC_SPC_NVM_CNFL_ATTR 0x80 /* Conflicting Attributes */ 1855cf840871SPaul Winder #define NVME_CQE_SC_SPC_NVM_INV_PROT 0x81 /* Invalid Protection */ 1856cf840871SPaul Winder #define NVME_CQE_SC_SPC_NVM_READONLY 0x82 /* Write to Read Only Range */ 1857e7efdd31SRobert Mustacchi /* Added in 2.0 */ 1858e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_IO_LIMIT 0x83 /* Cmd Size Limit Exceeded */ 1859e7efdd31SRobert Mustacchi /* 0x84 to 0xb7 are reserved */ 1860e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ZONE_BDRY_ERR 0xb8 /* Zoned Boundary Error */ 1861e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ZONE_FULL 0xb9 /* Zone is Full */ 1862e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ZONE_RDONLY 0xba /* Zone is Read Only */ 1863e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ZONE_OFFLINE 0xbb /* Zone is Offline */ 1864e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ZONE_INV_WRITE 0xbc /* Zone Invalid Write */ 1865e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ZONE_ACT 0xbd /* Too May Active Zones */ 1866e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_ZONE_OPEN 0xbe /* Too May Open Zones */ 1867e7efdd31SRobert Mustacchi #define NVME_CQE_SC_SPC_INV_ZONE_TRANS 0xbf /* Invalid Zone State Trans */ 1868cf840871SPaul Winder 1869cf840871SPaul Winder /* NVMe completion status code (data / metadata integrity) */ 1870cf840871SPaul Winder #define NVME_CQE_SC_INT_NVM_WRITE 0x80 /* Write Fault */ 1871cf840871SPaul Winder #define NVME_CQE_SC_INT_NVM_READ 0x81 /* Unrecovered Read Error */ 1872cf840871SPaul Winder #define NVME_CQE_SC_INT_NVM_GUARD 0x82 /* Guard Check Error */ 1873cf840871SPaul Winder #define NVME_CQE_SC_INT_NVM_APPL_TAG 0x83 /* Application Tag Check Err */ 1874cf840871SPaul Winder #define NVME_CQE_SC_INT_NVM_REF_TAG 0x84 /* Reference Tag Check Err */ 1875cf840871SPaul Winder #define NVME_CQE_SC_INT_NVM_COMPARE 0x85 /* Compare Failure */ 1876cf840871SPaul Winder #define NVME_CQE_SC_INT_NVM_ACCESS 0x86 /* Access Denied */ 1877e7efdd31SRobert Mustacchi /* Added in 1.2 */ 1878e7efdd31SRobert Mustacchi #define NVME_CQE_SC_INT_NVM_DEALLOC 0x87 /* Dealloc Log Block */ 1879e7efdd31SRobert Mustacchi /* Added in 2.0 */ 1880e7efdd31SRobert Mustacchi #define NVME_CQE_SC_INT_NVM_TAG 0x88 /* End-to-End Storage Tag Err */ 1881e7efdd31SRobert Mustacchi 1882e7efdd31SRobert Mustacchi /* NVMe completion status code (path related) */ 1883e7efdd31SRobert Mustacchi /* Added in NVMe 1.4 */ 1884e7efdd31SRobert Mustacchi #define NVME_CQE_SC_PATH_INT_ERR 0x00 /* Internal Path Error */ 1885e7efdd31SRobert Mustacchi #define NVME_CQE_SC_PATH_AA_PLOSS 0x01 /* Asym Access Pers Loss */ 1886e7efdd31SRobert Mustacchi #define NVME_CQE_SC_PATH_AA_INACC 0x02 /* Asym Access Inaccessible */ 1887e7efdd31SRobert Mustacchi #define NVME_CQE_SC_PATH_AA_TRANS 0x03 /* Asym Access Transition */ 1888e7efdd31SRobert Mustacchi #define NVME_CQE_SC_PATH_CTRL_ERR 0x60 /* Controller Path Error */ 1889e7efdd31SRobert Mustacchi #define NVME_CQE_SC_PATH_HOST_ERR 0x70 /* Host Path Error */ 1890e7efdd31SRobert Mustacchi #define NVME_CQE_SC_PATH_HOST_ABRT 0x71 /* Cmd aborted by host */ 18913d9b1a2aSHans Rosenfeld 1892eb7b3ff7SBenjamin Naecker /* 1893533affcbSRobert Mustacchi * Controller information (NVME_IOC_CTRL_INFO). This is a consolidation of misc. 1894533affcbSRobert Mustacchi * information that we want to know about a controller. 1895eb7b3ff7SBenjamin Naecker */ 1896eb7b3ff7SBenjamin Naecker typedef struct { 1897533affcbSRobert Mustacchi nvme_ioctl_common_t nci_common; 1898533affcbSRobert Mustacchi nvme_identify_ctrl_t nci_ctrl_id; 1899533affcbSRobert Mustacchi nvme_identify_nsid_t nci_common_ns; 1900533affcbSRobert Mustacchi nvme_version_t nci_vers; 1901533affcbSRobert Mustacchi nvme_capabilities_t nci_caps; 1902533affcbSRobert Mustacchi uint32_t nci_nintrs; 1903533affcbSRobert Mustacchi } nvme_ioctl_ctrl_info_t; 1904eb7b3ff7SBenjamin Naecker 1905baf9a850SHans Rosenfeld /* 1906744642a2SRobert Mustacchi * NVME namespace state flags. 1907baf9a850SHans Rosenfeld * 1908baf9a850SHans Rosenfeld * The values are defined entirely by the driver. Some states correspond to 1909baf9a850SHans Rosenfeld * namespace states described by the NVMe specification r1.3 section 6.1, others 1910744642a2SRobert Mustacchi * are specific to the implementation of this driver. These are present in the 1911533affcbSRobert Mustacchi * nvme_ns_kinfo_t that is used with the NVME_IOC_NS_INFO ioctl. 1912baf9a850SHans Rosenfeld * 1913baf9a850SHans Rosenfeld * The states are as follows: 1914baf9a850SHans Rosenfeld * - ALLOCATED: the namespace exists in the controller as per the NVMe spec 1915baf9a850SHans Rosenfeld * - ACTIVE: the namespace exists and is attached to this controller as per the 1916baf9a850SHans Rosenfeld * NVMe spec. Any namespace that is ACTIVE is also ALLOCATED. This must not be 1917baf9a850SHans Rosenfeld * confused with the ATTACHED state. 1918baf9a850SHans Rosenfeld * - ATTACHED: the driver has attached a blkdev(4D) instance to this namespace. 1919baf9a850SHans Rosenfeld * This state can be changed by userspace with the ioctls NVME_IOC_ATTACH and 1920baf9a850SHans Rosenfeld * NVME_IOC_DETACH. A namespace can only be ATTACHED when it is not IGNORED. 1921baf9a850SHans Rosenfeld * - IGNORED: the driver ignores this namespace, it never attaches a blkdev(4D). 1922baf9a850SHans Rosenfeld * Namespaces are IGNORED when they are not ACTIVE, or if they are ACTIVE but 1923baf9a850SHans Rosenfeld * have certain properties that the driver cannot handle. 1924baf9a850SHans Rosenfeld */ 1925744642a2SRobert Mustacchi typedef enum { 1926744642a2SRobert Mustacchi NVME_NS_STATE_ALLOCATED = 1 << 0, 1927744642a2SRobert Mustacchi NVME_NS_STATE_ACTIVE = 1 << 1, 1928744642a2SRobert Mustacchi NVME_NS_STATE_ATTACHED = 1 << 2, 1929744642a2SRobert Mustacchi NVME_NS_STATE_IGNORED = 1 << 3 1930744642a2SRobert Mustacchi } nvme_ns_state_t; 1931744642a2SRobert Mustacchi 1932744642a2SRobert Mustacchi /* 1933744642a2SRobert Mustacchi * This is the maximum length of the NVMe namespace's blkdev address. This is 1934744642a2SRobert Mustacchi * only valid in the structure with the NVME_NS_STATE_ATTACHED flag is set. 1935744642a2SRobert Mustacchi * Otherwise the entry will be all zeros. This is useful when you need to 1936744642a2SRobert Mustacchi * determine what the corresponding blkdev instance in libdevinfo for the 1937744642a2SRobert Mustacchi * device. 1938744642a2SRobert Mustacchi */ 1939744642a2SRobert Mustacchi #define NVME_BLKDEV_NAMELEN 128 1940744642a2SRobert Mustacchi 1941533affcbSRobert Mustacchi /* 1942533affcbSRobert Mustacchi * Namespace Information (NVME_IOC_NS_INFO). 1943533affcbSRobert Mustacchi */ 1944744642a2SRobert Mustacchi typedef struct { 1945533affcbSRobert Mustacchi nvme_ioctl_common_t nni_common; 1946744642a2SRobert Mustacchi nvme_ns_state_t nni_state; 1947744642a2SRobert Mustacchi char nni_addr[NVME_BLKDEV_NAMELEN]; 1948744642a2SRobert Mustacchi nvme_identify_nsid_t nni_id; 1949533affcbSRobert Mustacchi } nvme_ioctl_ns_info_t; 1950533affcbSRobert Mustacchi 1951533affcbSRobert Mustacchi /* 1952533affcbSRobert Mustacchi * NVMe Command Set Identifiers. This was added in NVMe 2.0, but in all the 1953533affcbSRobert Mustacchi * places it was required to be specified, the default value of 0 indicates the 1954533affcbSRobert Mustacchi * traditional NVM command set. 1955533affcbSRobert Mustacchi */ 1956533affcbSRobert Mustacchi typedef enum { 1957533affcbSRobert Mustacchi NVME_CSI_NVM = 0, 1958533affcbSRobert Mustacchi NVME_CSI_KV, 1959533affcbSRobert Mustacchi NVME_CSI_ZNS 1960533affcbSRobert Mustacchi } nvme_csi_t; 1961baf9a850SHans Rosenfeld 19623d9b1a2aSHans Rosenfeld #ifdef __cplusplus 19633d9b1a2aSHans Rosenfeld } 19643d9b1a2aSHans Rosenfeld #endif 19653d9b1a2aSHans Rosenfeld 19663d9b1a2aSHans Rosenfeld #endif /* _SYS_NVME_H */ 1967