1*ecee5a1fSHans Rosenfeld /* 2*ecee5a1fSHans Rosenfeld * This file and its contents are supplied under the terms of the 3*ecee5a1fSHans Rosenfeld * Common Development and Distribution License ("CDDL"), version 1.0. 4*ecee5a1fSHans Rosenfeld * You may only use this file in accordance with the terms of version 5*ecee5a1fSHans Rosenfeld * 1.0 of the CDDL. 6*ecee5a1fSHans Rosenfeld * 7*ecee5a1fSHans Rosenfeld * A full copy of the text of the CDDL should have accompanied this 8*ecee5a1fSHans Rosenfeld * source. A copy of the CDDL is also available via the Internet at 9*ecee5a1fSHans Rosenfeld * http://www.illumos.org/license/CDDL. 10*ecee5a1fSHans Rosenfeld */ 11*ecee5a1fSHans Rosenfeld 12*ecee5a1fSHans Rosenfeld /* 13*ecee5a1fSHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc. 14*ecee5a1fSHans Rosenfeld */ 15*ecee5a1fSHans Rosenfeld 16*ecee5a1fSHans Rosenfeld #ifndef _SYS_NVME_H 17*ecee5a1fSHans Rosenfeld #define _SYS_NVME_H 18*ecee5a1fSHans Rosenfeld 19*ecee5a1fSHans Rosenfeld #include <sys/types.h> 20*ecee5a1fSHans Rosenfeld 21*ecee5a1fSHans Rosenfeld #ifdef _KERNEL 22*ecee5a1fSHans Rosenfeld #include <sys/types32.h> 23*ecee5a1fSHans Rosenfeld #else 24*ecee5a1fSHans Rosenfeld #include <stdint.h> 25*ecee5a1fSHans Rosenfeld #endif 26*ecee5a1fSHans Rosenfeld 27*ecee5a1fSHans Rosenfeld /* 28*ecee5a1fSHans Rosenfeld * Declarations used for communication between nvmeadm(1M) and nvme(7D) 29*ecee5a1fSHans Rosenfeld */ 30*ecee5a1fSHans Rosenfeld 31*ecee5a1fSHans Rosenfeld #ifdef __cplusplus 32*ecee5a1fSHans Rosenfeld extern "C" { 33*ecee5a1fSHans Rosenfeld #endif 34*ecee5a1fSHans Rosenfeld 35*ecee5a1fSHans Rosenfeld /* 36*ecee5a1fSHans Rosenfeld * NVMe ioctl definitions 37*ecee5a1fSHans Rosenfeld */ 38*ecee5a1fSHans Rosenfeld 39*ecee5a1fSHans Rosenfeld #define NVME_IOC (('N' << 24) | ('V' << 16) | ('M' << 8)) 40*ecee5a1fSHans Rosenfeld #define NVME_IOC_IDENTIFY_CTRL (NVME_IOC | 1) 41*ecee5a1fSHans Rosenfeld #define NVME_IOC_IDENTIFY_NSID (NVME_IOC | 2) 42*ecee5a1fSHans Rosenfeld #define NVME_IOC_CAPABILITIES (NVME_IOC | 3) 43*ecee5a1fSHans Rosenfeld #define NVME_IOC_GET_LOGPAGE (NVME_IOC | 4) 44*ecee5a1fSHans Rosenfeld #define NVME_IOC_GET_FEATURES (NVME_IOC | 5) 45*ecee5a1fSHans Rosenfeld #define NVME_IOC_INTR_CNT (NVME_IOC | 6) 46*ecee5a1fSHans Rosenfeld #define NVME_IOC_VERSION (NVME_IOC | 7) 47*ecee5a1fSHans Rosenfeld #define NVME_IOC_FORMAT (NVME_IOC | 8) 48*ecee5a1fSHans Rosenfeld #define NVME_IOC_DETACH (NVME_IOC | 9) 49*ecee5a1fSHans Rosenfeld #define NVME_IOC_ATTACH (NVME_IOC | 10) 50*ecee5a1fSHans Rosenfeld #define NVME_IOC_MAX NVME_IOC_ATTACH 51*ecee5a1fSHans Rosenfeld 52*ecee5a1fSHans Rosenfeld #define IS_NVME_IOC(x) ((x) > NVME_IOC && (x) <= NVME_IOC_MAX) 53*ecee5a1fSHans Rosenfeld #define NVME_IOC_CMD(x) ((x) & 0xff) 54*ecee5a1fSHans Rosenfeld 55*ecee5a1fSHans Rosenfeld typedef struct { 56*ecee5a1fSHans Rosenfeld size_t n_len; 57*ecee5a1fSHans Rosenfeld uintptr_t n_buf; 58*ecee5a1fSHans Rosenfeld uint64_t n_arg; 59*ecee5a1fSHans Rosenfeld } nvme_ioctl_t; 60*ecee5a1fSHans Rosenfeld 61*ecee5a1fSHans Rosenfeld #ifdef _KERNEL 62*ecee5a1fSHans Rosenfeld typedef struct { 63*ecee5a1fSHans Rosenfeld size32_t n_len; 64*ecee5a1fSHans Rosenfeld uintptr32_t n_buf; 65*ecee5a1fSHans Rosenfeld uint64_t n_arg; 66*ecee5a1fSHans Rosenfeld } nvme_ioctl32_t; 67*ecee5a1fSHans Rosenfeld #endif 68*ecee5a1fSHans Rosenfeld 69*ecee5a1fSHans Rosenfeld /* 70*ecee5a1fSHans Rosenfeld * NVMe capabilities 71*ecee5a1fSHans Rosenfeld */ 72*ecee5a1fSHans Rosenfeld typedef struct { 73*ecee5a1fSHans Rosenfeld uint32_t mpsmax; /* Memory Page Size Maximum */ 74*ecee5a1fSHans Rosenfeld uint32_t mpsmin; /* Memory Page Size Minimum */ 75*ecee5a1fSHans Rosenfeld } nvme_capabilities_t; 76*ecee5a1fSHans Rosenfeld 77*ecee5a1fSHans Rosenfeld /* 78*ecee5a1fSHans Rosenfeld * NVMe version 79*ecee5a1fSHans Rosenfeld */ 80*ecee5a1fSHans Rosenfeld typedef struct { 81*ecee5a1fSHans Rosenfeld uint16_t v_minor; 82*ecee5a1fSHans Rosenfeld uint16_t v_major; 83*ecee5a1fSHans Rosenfeld } nvme_version_t; 84*ecee5a1fSHans Rosenfeld 85*ecee5a1fSHans Rosenfeld #define NVME_VERSION_ATLEAST(v, maj, min) \ 86*ecee5a1fSHans Rosenfeld (((v)->v_major) > (maj) || \ 87*ecee5a1fSHans Rosenfeld ((v)->v_major == (maj) && (v)->v_minor >= (min))) 88*ecee5a1fSHans Rosenfeld 89*ecee5a1fSHans Rosenfeld #define NVME_VERSION_HIGHER(v, maj, min) \ 90*ecee5a1fSHans Rosenfeld (((v)->v_major) > (maj) || \ 91*ecee5a1fSHans Rosenfeld ((v)->v_major == (maj) && (v)->v_minor > (min))) 92*ecee5a1fSHans Rosenfeld 93*ecee5a1fSHans Rosenfeld 94*ecee5a1fSHans Rosenfeld #pragma pack(1) 95*ecee5a1fSHans Rosenfeld 96*ecee5a1fSHans Rosenfeld /* 97*ecee5a1fSHans Rosenfeld * NVMe Identify data structures 98*ecee5a1fSHans Rosenfeld */ 99*ecee5a1fSHans Rosenfeld 100*ecee5a1fSHans Rosenfeld #define NVME_IDENTIFY_BUFSIZE 4096 /* buffer size for Identify */ 101*ecee5a1fSHans Rosenfeld 102*ecee5a1fSHans Rosenfeld /* NVMe Queue Entry Size bitfield */ 103*ecee5a1fSHans Rosenfeld typedef struct { 104*ecee5a1fSHans Rosenfeld uint8_t qes_min:4; /* minimum entry size */ 105*ecee5a1fSHans Rosenfeld uint8_t qes_max:4; /* maximum entry size */ 106*ecee5a1fSHans Rosenfeld } nvme_idctl_qes_t; 107*ecee5a1fSHans Rosenfeld 108*ecee5a1fSHans Rosenfeld /* NVMe Power State Descriptor */ 109*ecee5a1fSHans Rosenfeld typedef struct { 110*ecee5a1fSHans Rosenfeld uint16_t psd_mp; /* Maximum Power */ 111*ecee5a1fSHans Rosenfeld uint8_t psd_rsvd1; 112*ecee5a1fSHans Rosenfeld uint8_t psd_mps:1; /* Max Power Scale (1.1) */ 113*ecee5a1fSHans Rosenfeld uint8_t psd_nops:1; /* Non-Operational State (1.1) */ 114*ecee5a1fSHans Rosenfeld uint8_t psd_rsvd2:6; 115*ecee5a1fSHans Rosenfeld uint32_t psd_enlat; /* Entry Latency */ 116*ecee5a1fSHans Rosenfeld uint32_t psd_exlat; /* Exit Latency */ 117*ecee5a1fSHans Rosenfeld uint8_t psd_rrt:5; /* Relative Read Throughput */ 118*ecee5a1fSHans Rosenfeld uint8_t psd_rsvd3:3; 119*ecee5a1fSHans Rosenfeld uint8_t psd_rrl:5; /* Relative Read Latency */ 120*ecee5a1fSHans Rosenfeld uint8_t psd_rsvd4:3; 121*ecee5a1fSHans Rosenfeld uint8_t psd_rwt:5; /* Relative Write Throughput */ 122*ecee5a1fSHans Rosenfeld uint8_t psd_rsvd5:3; 123*ecee5a1fSHans Rosenfeld uint8_t psd_rwl:5; /* Relative Write Latency */ 124*ecee5a1fSHans Rosenfeld uint8_t psd_rsvd6:3; 125*ecee5a1fSHans Rosenfeld uint8_t psd_rsvd7[16]; 126*ecee5a1fSHans Rosenfeld } nvme_idctl_psd_t; 127*ecee5a1fSHans Rosenfeld 128*ecee5a1fSHans Rosenfeld /* NVMe Identify Controller Data Structure */ 129*ecee5a1fSHans Rosenfeld typedef struct { 130*ecee5a1fSHans Rosenfeld /* Controller Capabilities & Features */ 131*ecee5a1fSHans Rosenfeld uint16_t id_vid; /* PCI vendor ID */ 132*ecee5a1fSHans Rosenfeld uint16_t id_ssvid; /* PCI subsystem vendor ID */ 133*ecee5a1fSHans Rosenfeld char id_serial[20]; /* Serial Number */ 134*ecee5a1fSHans Rosenfeld char id_model[40]; /* Model Number */ 135*ecee5a1fSHans Rosenfeld char id_fwrev[8]; /* Firmware Revision */ 136*ecee5a1fSHans Rosenfeld uint8_t id_rab; /* Recommended Arbitration Burst */ 137*ecee5a1fSHans Rosenfeld uint8_t id_oui[3]; /* vendor IEEE OUI */ 138*ecee5a1fSHans Rosenfeld struct { /* Multi-Interface Capabilities */ 139*ecee5a1fSHans Rosenfeld uint8_t m_multi_pci:1; /* HW has multiple PCIe interfaces */ 140*ecee5a1fSHans Rosenfeld uint8_t m_multi_ctrl:1; /* HW has multiple controllers (1.1) */ 141*ecee5a1fSHans Rosenfeld uint8_t m_sr_iov:1; /* controller is SR-IOV virt fn (1.1) */ 142*ecee5a1fSHans Rosenfeld uint8_t m_rsvd:5; 143*ecee5a1fSHans Rosenfeld } id_mic; 144*ecee5a1fSHans Rosenfeld uint8_t id_mdts; /* Maximum Data Transfer Size */ 145*ecee5a1fSHans Rosenfeld uint16_t id_cntlid; /* Unique Controller Identifier (1.1) */ 146*ecee5a1fSHans Rosenfeld uint8_t id_rsvd_cc[256 - 80]; 147*ecee5a1fSHans Rosenfeld 148*ecee5a1fSHans Rosenfeld /* Admin Command Set Attributes */ 149*ecee5a1fSHans Rosenfeld struct { /* Optional Admin Command Support */ 150*ecee5a1fSHans Rosenfeld uint16_t oa_security:1; /* Security Send & Receive */ 151*ecee5a1fSHans Rosenfeld uint16_t oa_format:1; /* Format NVM */ 152*ecee5a1fSHans Rosenfeld uint16_t oa_firmware:1; /* Firmware Activate & Download */ 153*ecee5a1fSHans Rosenfeld uint16_t oa_rsvd:13; 154*ecee5a1fSHans Rosenfeld } id_oacs; 155*ecee5a1fSHans Rosenfeld uint8_t id_acl; /* Abort Command Limit */ 156*ecee5a1fSHans Rosenfeld uint8_t id_aerl; /* Asynchronous Event Request Limit */ 157*ecee5a1fSHans Rosenfeld struct { /* Firmware Updates */ 158*ecee5a1fSHans Rosenfeld uint8_t fw_readonly:1; /* Slot 1 is Read-Only */ 159*ecee5a1fSHans Rosenfeld uint8_t fw_nslot:3; /* number of firmware slots */ 160*ecee5a1fSHans Rosenfeld uint8_t fw_rsvd:4; 161*ecee5a1fSHans Rosenfeld } id_frmw; 162*ecee5a1fSHans Rosenfeld struct { /* Log Page Attributes */ 163*ecee5a1fSHans Rosenfeld uint8_t lp_smart:1; /* SMART/Health information per NS */ 164*ecee5a1fSHans Rosenfeld uint8_t lp_rsvd:7; 165*ecee5a1fSHans Rosenfeld } id_lpa; 166*ecee5a1fSHans Rosenfeld uint8_t id_elpe; /* Error Log Page Entries */ 167*ecee5a1fSHans Rosenfeld uint8_t id_npss; /* Number of Power States */ 168*ecee5a1fSHans Rosenfeld struct { /* Admin Vendor Specific Command Conf */ 169*ecee5a1fSHans Rosenfeld uint8_t av_spec:1; /* use format from spec */ 170*ecee5a1fSHans Rosenfeld uint8_t av_rsvd:7; 171*ecee5a1fSHans Rosenfeld } id_avscc; 172*ecee5a1fSHans Rosenfeld struct { /* Autonomous Power State Trans (1.1) */ 173*ecee5a1fSHans Rosenfeld uint8_t ap_sup:1; /* APST supported (1.1) */ 174*ecee5a1fSHans Rosenfeld uint8_t ap_rsvd:7; 175*ecee5a1fSHans Rosenfeld } id_apsta; 176*ecee5a1fSHans Rosenfeld uint8_t id_rsvd_ac[256 - 10]; 177*ecee5a1fSHans Rosenfeld 178*ecee5a1fSHans Rosenfeld /* NVM Command Set Attributes */ 179*ecee5a1fSHans Rosenfeld nvme_idctl_qes_t id_sqes; /* Submission Queue Entry Size */ 180*ecee5a1fSHans Rosenfeld nvme_idctl_qes_t id_cqes; /* Completion Queue Entry Size */ 181*ecee5a1fSHans Rosenfeld uint16_t id_rsvd_nc_1; 182*ecee5a1fSHans Rosenfeld uint32_t id_nn; /* Number of Namespaces */ 183*ecee5a1fSHans Rosenfeld struct { /* Optional NVM Command Support */ 184*ecee5a1fSHans Rosenfeld uint16_t on_compare:1; /* Compare */ 185*ecee5a1fSHans Rosenfeld uint16_t on_wr_unc:1; /* Write Uncorrectable */ 186*ecee5a1fSHans Rosenfeld uint16_t on_dset_mgmt:1; /* Dataset Management */ 187*ecee5a1fSHans Rosenfeld uint16_t on_wr_zero:1; /* Write Zeros (1.1) */ 188*ecee5a1fSHans Rosenfeld uint16_t on_save:1; /* Save/Select in Get/Set Feat (1.1) */ 189*ecee5a1fSHans Rosenfeld uint16_t on_reserve:1; /* Reservations (1.1) */ 190*ecee5a1fSHans Rosenfeld uint16_t on_rsvd:10; 191*ecee5a1fSHans Rosenfeld } id_oncs; 192*ecee5a1fSHans Rosenfeld struct { /* Fused Operation Support */ 193*ecee5a1fSHans Rosenfeld uint16_t f_cmp_wr:1; /* Compare and Write */ 194*ecee5a1fSHans Rosenfeld uint16_t f_rsvd:15; 195*ecee5a1fSHans Rosenfeld } id_fuses; 196*ecee5a1fSHans Rosenfeld struct { /* Format NVM Attributes */ 197*ecee5a1fSHans Rosenfeld uint8_t fn_format:1; /* Format applies to all NS */ 198*ecee5a1fSHans Rosenfeld uint8_t fn_sec_erase:1; /* Secure Erase applies to all NS */ 199*ecee5a1fSHans Rosenfeld uint8_t fn_crypt_erase:1; /* Cryptographic Erase supported */ 200*ecee5a1fSHans Rosenfeld uint8_t fn_rsvd:5; 201*ecee5a1fSHans Rosenfeld } id_fna; 202*ecee5a1fSHans Rosenfeld struct { /* Volatile Write Cache */ 203*ecee5a1fSHans Rosenfeld uint8_t vwc_present:1; /* Volatile Write Cache present */ 204*ecee5a1fSHans Rosenfeld uint8_t rsvd:7; 205*ecee5a1fSHans Rosenfeld } id_vwc; 206*ecee5a1fSHans Rosenfeld uint16_t id_awun; /* Atomic Write Unit Normal */ 207*ecee5a1fSHans Rosenfeld uint16_t id_awupf; /* Atomic Write Unit Power Fail */ 208*ecee5a1fSHans Rosenfeld struct { /* NVM Vendor Specific Command Conf */ 209*ecee5a1fSHans Rosenfeld uint8_t nv_spec:1; /* use format from spec */ 210*ecee5a1fSHans Rosenfeld uint8_t nv_rsvd:7; 211*ecee5a1fSHans Rosenfeld } id_nvscc; 212*ecee5a1fSHans Rosenfeld uint8_t id_rsvd_nc_2; 213*ecee5a1fSHans Rosenfeld uint16_t id_acwu; /* Atomic Compare & Write Unit (1.1) */ 214*ecee5a1fSHans Rosenfeld uint16_t id_rsvd_nc_3; 215*ecee5a1fSHans Rosenfeld struct { /* SGL Support (1.1) */ 216*ecee5a1fSHans Rosenfeld uint16_t sgl_sup:1; /* SGL Supported in NVM cmds (1.1) */ 217*ecee5a1fSHans Rosenfeld uint16_t sgl_rsvd1:15; 218*ecee5a1fSHans Rosenfeld uint16_t sgl_bucket:1; /* SGL Bit Bucket supported (1.1) */ 219*ecee5a1fSHans Rosenfeld uint16_t sgl_rsvd2:15; 220*ecee5a1fSHans Rosenfeld } id_sgls; 221*ecee5a1fSHans Rosenfeld uint8_t id_rsvd_nc_4[192 - 28]; 222*ecee5a1fSHans Rosenfeld 223*ecee5a1fSHans Rosenfeld /* I/O Command Set Attributes */ 224*ecee5a1fSHans Rosenfeld uint8_t id_rsvd_ioc[1344]; 225*ecee5a1fSHans Rosenfeld 226*ecee5a1fSHans Rosenfeld /* Power State Descriptors */ 227*ecee5a1fSHans Rosenfeld nvme_idctl_psd_t id_psd[32]; 228*ecee5a1fSHans Rosenfeld 229*ecee5a1fSHans Rosenfeld /* Vendor Specific */ 230*ecee5a1fSHans Rosenfeld uint8_t id_vs[1024]; 231*ecee5a1fSHans Rosenfeld } nvme_identify_ctrl_t; 232*ecee5a1fSHans Rosenfeld 233*ecee5a1fSHans Rosenfeld /* NVMe Identify Namespace LBA Format */ 234*ecee5a1fSHans Rosenfeld typedef struct { 235*ecee5a1fSHans Rosenfeld uint16_t lbaf_ms; /* Metadata Size */ 236*ecee5a1fSHans Rosenfeld uint8_t lbaf_lbads; /* LBA Data Size */ 237*ecee5a1fSHans Rosenfeld uint8_t lbaf_rp:2; /* Relative Performance */ 238*ecee5a1fSHans Rosenfeld uint8_t lbaf_rsvd1:6; 239*ecee5a1fSHans Rosenfeld } nvme_idns_lbaf_t; 240*ecee5a1fSHans Rosenfeld 241*ecee5a1fSHans Rosenfeld /* NVMe Identify Namespace Data Structure */ 242*ecee5a1fSHans Rosenfeld typedef struct { 243*ecee5a1fSHans Rosenfeld uint64_t id_nsize; /* Namespace Size */ 244*ecee5a1fSHans Rosenfeld uint64_t id_ncap; /* Namespace Capacity */ 245*ecee5a1fSHans Rosenfeld uint64_t id_nuse; /* Namespace Utilization */ 246*ecee5a1fSHans Rosenfeld struct { /* Namespace Features */ 247*ecee5a1fSHans Rosenfeld uint8_t f_thin:1; /* Thin Provisioning */ 248*ecee5a1fSHans Rosenfeld uint8_t f_rsvd:7; 249*ecee5a1fSHans Rosenfeld } id_nsfeat; 250*ecee5a1fSHans Rosenfeld uint8_t id_nlbaf; /* Number of LBA formats */ 251*ecee5a1fSHans Rosenfeld struct { /* Formatted LBA size */ 252*ecee5a1fSHans Rosenfeld uint8_t lba_format:4; /* LBA format */ 253*ecee5a1fSHans Rosenfeld uint8_t lba_extlba:1; /* extended LBA (includes metadata) */ 254*ecee5a1fSHans Rosenfeld uint8_t lba_rsvd:3; 255*ecee5a1fSHans Rosenfeld } id_flbas; 256*ecee5a1fSHans Rosenfeld struct { /* Metadata Capabilities */ 257*ecee5a1fSHans Rosenfeld uint8_t mc_extlba:1; /* extended LBA transfers */ 258*ecee5a1fSHans Rosenfeld uint8_t mc_separate:1; /* separate metadata transfers */ 259*ecee5a1fSHans Rosenfeld uint8_t mc_rsvd:6; 260*ecee5a1fSHans Rosenfeld } id_mc; 261*ecee5a1fSHans Rosenfeld struct { /* Data Protection Capabilities */ 262*ecee5a1fSHans Rosenfeld uint8_t dp_type1:1; /* Protection Information Type 1 */ 263*ecee5a1fSHans Rosenfeld uint8_t dp_type2:1; /* Protection Information Type 2 */ 264*ecee5a1fSHans Rosenfeld uint8_t dp_type3:1; /* Protection Information Type 3 */ 265*ecee5a1fSHans Rosenfeld uint8_t dp_first:1; /* first 8 bytes of metadata */ 266*ecee5a1fSHans Rosenfeld uint8_t dp_last:1; /* last 8 bytes of metadata */ 267*ecee5a1fSHans Rosenfeld uint8_t dp_rsvd:3; 268*ecee5a1fSHans Rosenfeld } id_dpc; 269*ecee5a1fSHans Rosenfeld struct { /* Data Protection Settings */ 270*ecee5a1fSHans Rosenfeld uint8_t dp_pinfo:3; /* Protection Information enabled */ 271*ecee5a1fSHans Rosenfeld uint8_t dp_first:1; /* first 8 bytes of metadata */ 272*ecee5a1fSHans Rosenfeld uint8_t dp_rsvd:4; 273*ecee5a1fSHans Rosenfeld } id_dps; 274*ecee5a1fSHans Rosenfeld struct { /* NS Multi-Path/Sharing Cap (1.1) */ 275*ecee5a1fSHans Rosenfeld uint8_t nm_shared:1; /* NS is shared (1.1) */ 276*ecee5a1fSHans Rosenfeld uint8_t nm_rsvd:7; 277*ecee5a1fSHans Rosenfeld } id_nmic; 278*ecee5a1fSHans Rosenfeld struct { /* Reservation Capabilities (1.1) */ 279*ecee5a1fSHans Rosenfeld uint8_t rc_persist:1; /* Persist Through Power Loss (1.1) */ 280*ecee5a1fSHans Rosenfeld uint8_t rc_wr_excl:1; /* Write Exclusive (1.1) */ 281*ecee5a1fSHans Rosenfeld uint8_t rc_excl:1; /* Exclusive Access (1.1) */ 282*ecee5a1fSHans Rosenfeld uint8_t rc_wr_excl_r:1; /* Wr Excl - Registrants Only (1.1) */ 283*ecee5a1fSHans Rosenfeld uint8_t rc_excl_r:1; /* Excl Acc - Registrants Only (1.1) */ 284*ecee5a1fSHans Rosenfeld uint8_t rc_wr_excl_a:1; /* Wr Excl - All Registrants (1.1) */ 285*ecee5a1fSHans Rosenfeld uint8_t rc_excl_a:1; /* Excl Acc - All Registrants (1.1) */ 286*ecee5a1fSHans Rosenfeld uint8_t rc_rsvd:1; 287*ecee5a1fSHans Rosenfeld } id_rescap; 288*ecee5a1fSHans Rosenfeld uint8_t id_rsvd1[120 - 32]; 289*ecee5a1fSHans Rosenfeld uint8_t id_eui64[8]; /* IEEE Extended Unique Id (1.1) */ 290*ecee5a1fSHans Rosenfeld nvme_idns_lbaf_t id_lbaf[16]; /* LBA Formats */ 291*ecee5a1fSHans Rosenfeld 292*ecee5a1fSHans Rosenfeld uint8_t id_rsvd2[192]; 293*ecee5a1fSHans Rosenfeld 294*ecee5a1fSHans Rosenfeld uint8_t id_vs[3712]; /* Vendor Specific */ 295*ecee5a1fSHans Rosenfeld } nvme_identify_nsid_t; 296*ecee5a1fSHans Rosenfeld 297*ecee5a1fSHans Rosenfeld 298*ecee5a1fSHans Rosenfeld /* 299*ecee5a1fSHans Rosenfeld * NVMe completion queue entry status field 300*ecee5a1fSHans Rosenfeld */ 301*ecee5a1fSHans Rosenfeld typedef struct { 302*ecee5a1fSHans Rosenfeld uint16_t sf_p:1; /* Phase Tag */ 303*ecee5a1fSHans Rosenfeld uint16_t sf_sc:8; /* Status Code */ 304*ecee5a1fSHans Rosenfeld uint16_t sf_sct:3; /* Status Code Type */ 305*ecee5a1fSHans Rosenfeld uint16_t sf_rsvd2:2; 306*ecee5a1fSHans Rosenfeld uint16_t sf_m:1; /* More */ 307*ecee5a1fSHans Rosenfeld uint16_t sf_dnr:1; /* Do Not Retry */ 308*ecee5a1fSHans Rosenfeld } nvme_cqe_sf_t; 309*ecee5a1fSHans Rosenfeld 310*ecee5a1fSHans Rosenfeld 311*ecee5a1fSHans Rosenfeld /* 312*ecee5a1fSHans Rosenfeld * NVMe Get Log Page 313*ecee5a1fSHans Rosenfeld */ 314*ecee5a1fSHans Rosenfeld #define NVME_LOGPAGE_ERROR 0x1 /* Error Information */ 315*ecee5a1fSHans Rosenfeld #define NVME_LOGPAGE_HEALTH 0x2 /* SMART/Health Information */ 316*ecee5a1fSHans Rosenfeld #define NVME_LOGPAGE_FWSLOT 0x3 /* Firmware Slot Information */ 317*ecee5a1fSHans Rosenfeld 318*ecee5a1fSHans Rosenfeld typedef struct { 319*ecee5a1fSHans Rosenfeld uint64_t el_count; /* Error Count */ 320*ecee5a1fSHans Rosenfeld uint16_t el_sqid; /* Submission Queue ID */ 321*ecee5a1fSHans Rosenfeld uint16_t el_cid; /* Command ID */ 322*ecee5a1fSHans Rosenfeld nvme_cqe_sf_t el_sf; /* Status Field */ 323*ecee5a1fSHans Rosenfeld uint8_t el_byte; /* Parameter Error Location byte */ 324*ecee5a1fSHans Rosenfeld uint8_t el_bit:3; /* Parameter Error Location bit */ 325*ecee5a1fSHans Rosenfeld uint8_t el_rsvd1:5; 326*ecee5a1fSHans Rosenfeld uint64_t el_lba; /* Logical Block Address */ 327*ecee5a1fSHans Rosenfeld uint32_t el_nsid; /* Namespace ID */ 328*ecee5a1fSHans Rosenfeld uint8_t el_vendor; /* Vendor Specific Information avail */ 329*ecee5a1fSHans Rosenfeld uint8_t el_rsvd2[64 - 29]; 330*ecee5a1fSHans Rosenfeld } nvme_error_log_entry_t; 331*ecee5a1fSHans Rosenfeld 332*ecee5a1fSHans Rosenfeld typedef struct { 333*ecee5a1fSHans Rosenfeld uint64_t lo; 334*ecee5a1fSHans Rosenfeld uint64_t hi; 335*ecee5a1fSHans Rosenfeld } nvme_uint128_t; 336*ecee5a1fSHans Rosenfeld 337*ecee5a1fSHans Rosenfeld typedef struct { 338*ecee5a1fSHans Rosenfeld struct { /* Critical Warning */ 339*ecee5a1fSHans Rosenfeld uint8_t cw_avail:1; /* available space too low */ 340*ecee5a1fSHans Rosenfeld uint8_t cw_temp:1; /* temperature too high */ 341*ecee5a1fSHans Rosenfeld uint8_t cw_reliab:1; /* degraded reliability */ 342*ecee5a1fSHans Rosenfeld uint8_t cw_readonly:1; /* media is read-only */ 343*ecee5a1fSHans Rosenfeld uint8_t cw_volatile:1; /* volatile memory backup failed */ 344*ecee5a1fSHans Rosenfeld uint8_t cw_rsvd:3; 345*ecee5a1fSHans Rosenfeld } hl_crit_warn; 346*ecee5a1fSHans Rosenfeld uint16_t hl_temp; /* Temperature */ 347*ecee5a1fSHans Rosenfeld uint8_t hl_avail_spare; /* Available Spare */ 348*ecee5a1fSHans Rosenfeld uint8_t hl_avail_spare_thr; /* Available Spare Threshold */ 349*ecee5a1fSHans Rosenfeld uint8_t hl_used; /* Percentage Used */ 350*ecee5a1fSHans Rosenfeld uint8_t hl_rsvd1[32 - 6]; 351*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_data_read; /* Data Units Read */ 352*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_data_write; /* Data Units Written */ 353*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_host_read; /* Host Read Commands */ 354*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_host_write; /* Host Write Commands */ 355*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_ctrl_busy; /* Controller Busy Time */ 356*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_power_cycles; /* Power Cycles */ 357*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_power_on_hours; /* Power On Hours */ 358*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_unsafe_shutdn; /* Unsafe Shutdowns */ 359*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_media_errors; /* Media Errors */ 360*ecee5a1fSHans Rosenfeld nvme_uint128_t hl_errors_logged; /* Number of errors logged */ 361*ecee5a1fSHans Rosenfeld uint8_t hl_rsvd2[512 - 192]; 362*ecee5a1fSHans Rosenfeld } nvme_health_log_t; 363*ecee5a1fSHans Rosenfeld 364*ecee5a1fSHans Rosenfeld typedef struct { 365*ecee5a1fSHans Rosenfeld uint8_t fw_afi:3; /* Active Firmware Slot */ 366*ecee5a1fSHans Rosenfeld uint8_t fw_rsvd1:5; 367*ecee5a1fSHans Rosenfeld uint8_t fw_rsvd2[7]; 368*ecee5a1fSHans Rosenfeld char fw_frs[7][8]; /* Firmware Revision / Slot */ 369*ecee5a1fSHans Rosenfeld uint8_t fw_rsvd3[512 - 64]; 370*ecee5a1fSHans Rosenfeld } nvme_fwslot_log_t; 371*ecee5a1fSHans Rosenfeld 372*ecee5a1fSHans Rosenfeld 373*ecee5a1fSHans Rosenfeld /* 374*ecee5a1fSHans Rosenfeld * NVMe Format NVM 375*ecee5a1fSHans Rosenfeld */ 376*ecee5a1fSHans Rosenfeld #define NVME_FRMT_SES_NONE 0 377*ecee5a1fSHans Rosenfeld #define NVME_FRMT_SES_USER 1 378*ecee5a1fSHans Rosenfeld #define NVME_FRMT_SES_CRYPTO 2 379*ecee5a1fSHans Rosenfeld #define NVME_FRMT_MAX_SES 2 380*ecee5a1fSHans Rosenfeld 381*ecee5a1fSHans Rosenfeld #define NVME_FRMT_MAX_LBAF 15 382*ecee5a1fSHans Rosenfeld 383*ecee5a1fSHans Rosenfeld typedef union { 384*ecee5a1fSHans Rosenfeld struct { 385*ecee5a1fSHans Rosenfeld uint32_t fm_lbaf:4; /* LBA Format */ 386*ecee5a1fSHans Rosenfeld uint32_t fm_ms:1; /* Metadata Settings */ 387*ecee5a1fSHans Rosenfeld uint32_t fm_pi:3; /* Protection Information */ 388*ecee5a1fSHans Rosenfeld uint32_t fm_pil:1; /* Prot. Information Location */ 389*ecee5a1fSHans Rosenfeld uint32_t fm_ses:3; /* Secure Erase Settings */ 390*ecee5a1fSHans Rosenfeld uint32_t fm_resvd:20; 391*ecee5a1fSHans Rosenfeld } b; 392*ecee5a1fSHans Rosenfeld uint32_t r; 393*ecee5a1fSHans Rosenfeld } nvme_format_nvm_t; 394*ecee5a1fSHans Rosenfeld 395*ecee5a1fSHans Rosenfeld 396*ecee5a1fSHans Rosenfeld /* 397*ecee5a1fSHans Rosenfeld * NVMe Get / Set Features 398*ecee5a1fSHans Rosenfeld */ 399*ecee5a1fSHans Rosenfeld #define NVME_FEAT_ARBITRATION 0x1 /* Command Arbitration */ 400*ecee5a1fSHans Rosenfeld #define NVME_FEAT_POWER_MGMT 0x2 /* Power Management */ 401*ecee5a1fSHans Rosenfeld #define NVME_FEAT_LBA_RANGE 0x3 /* LBA Range Type */ 402*ecee5a1fSHans Rosenfeld #define NVME_FEAT_TEMPERATURE 0x4 /* Temperature Threshold */ 403*ecee5a1fSHans Rosenfeld #define NVME_FEAT_ERROR 0x5 /* Error Recovery */ 404*ecee5a1fSHans Rosenfeld #define NVME_FEAT_WRITE_CACHE 0x6 /* Volatile Write Cache */ 405*ecee5a1fSHans Rosenfeld #define NVME_FEAT_NQUEUES 0x7 /* Number of Queues */ 406*ecee5a1fSHans Rosenfeld #define NVME_FEAT_INTR_COAL 0x8 /* Interrupt Coalescing */ 407*ecee5a1fSHans Rosenfeld #define NVME_FEAT_INTR_VECT 0x9 /* Interrupt Vector Configuration */ 408*ecee5a1fSHans Rosenfeld #define NVME_FEAT_WRITE_ATOM 0xa /* Write Atomicity */ 409*ecee5a1fSHans Rosenfeld #define NVME_FEAT_ASYNC_EVENT 0xb /* Asynchronous Event Configuration */ 410*ecee5a1fSHans Rosenfeld #define NVME_FEAT_AUTO_PST 0xc /* Autonomous Power State Transition */ 411*ecee5a1fSHans Rosenfeld /* (1.1) */ 412*ecee5a1fSHans Rosenfeld 413*ecee5a1fSHans Rosenfeld #define NVME_FEAT_PROGRESS 0x80 /* Software Progress Marker */ 414*ecee5a1fSHans Rosenfeld 415*ecee5a1fSHans Rosenfeld /* Arbitration Feature */ 416*ecee5a1fSHans Rosenfeld typedef union { 417*ecee5a1fSHans Rosenfeld struct { 418*ecee5a1fSHans Rosenfeld uint8_t arb_ab:3; /* Arbitration Burst */ 419*ecee5a1fSHans Rosenfeld uint8_t arb_rsvd:5; 420*ecee5a1fSHans Rosenfeld uint8_t arb_lpw; /* Low Priority Weight */ 421*ecee5a1fSHans Rosenfeld uint8_t arb_mpw; /* Medium Priority Weight */ 422*ecee5a1fSHans Rosenfeld uint8_t arb_hpw; /* High Priority Weight */ 423*ecee5a1fSHans Rosenfeld } b; 424*ecee5a1fSHans Rosenfeld uint32_t r; 425*ecee5a1fSHans Rosenfeld } nvme_arbitration_t; 426*ecee5a1fSHans Rosenfeld 427*ecee5a1fSHans Rosenfeld /* Power Management Feature */ 428*ecee5a1fSHans Rosenfeld typedef union { 429*ecee5a1fSHans Rosenfeld struct { 430*ecee5a1fSHans Rosenfeld uint32_t pm_ps:5; /* Power State */ 431*ecee5a1fSHans Rosenfeld uint32_t pm_rsvd:27; 432*ecee5a1fSHans Rosenfeld } b; 433*ecee5a1fSHans Rosenfeld uint32_t r; 434*ecee5a1fSHans Rosenfeld } nvme_power_mgmt_t; 435*ecee5a1fSHans Rosenfeld 436*ecee5a1fSHans Rosenfeld /* LBA Range Type Feature */ 437*ecee5a1fSHans Rosenfeld typedef union { 438*ecee5a1fSHans Rosenfeld struct { 439*ecee5a1fSHans Rosenfeld uint32_t lr_num:6; /* Number of LBA ranges */ 440*ecee5a1fSHans Rosenfeld uint32_t lr_rsvd:26; 441*ecee5a1fSHans Rosenfeld } b; 442*ecee5a1fSHans Rosenfeld uint32_t r; 443*ecee5a1fSHans Rosenfeld } nvme_lba_range_type_t; 444*ecee5a1fSHans Rosenfeld 445*ecee5a1fSHans Rosenfeld typedef struct { 446*ecee5a1fSHans Rosenfeld uint8_t lr_type; /* Type */ 447*ecee5a1fSHans Rosenfeld struct { /* Attributes */ 448*ecee5a1fSHans Rosenfeld uint8_t lr_write:1; /* may be overwritten */ 449*ecee5a1fSHans Rosenfeld uint8_t lr_hidden:1; /* hidden from OS/EFI/BIOS */ 450*ecee5a1fSHans Rosenfeld uint8_t lr_rsvd1:6; 451*ecee5a1fSHans Rosenfeld } lr_attr; 452*ecee5a1fSHans Rosenfeld uint8_t lr_rsvd2[14]; 453*ecee5a1fSHans Rosenfeld uint64_t lr_slba; /* Starting LBA */ 454*ecee5a1fSHans Rosenfeld uint64_t lr_nlb; /* Number of Logical Blocks */ 455*ecee5a1fSHans Rosenfeld uint8_t lr_guid[16]; /* Unique Identifier */ 456*ecee5a1fSHans Rosenfeld uint8_t lr_rsvd3[16]; 457*ecee5a1fSHans Rosenfeld } nvme_lba_range_t; 458*ecee5a1fSHans Rosenfeld 459*ecee5a1fSHans Rosenfeld #define NVME_LBA_RANGE_BUFSIZE 4096 460*ecee5a1fSHans Rosenfeld 461*ecee5a1fSHans Rosenfeld /* Temperature Threshold Feature */ 462*ecee5a1fSHans Rosenfeld typedef union { 463*ecee5a1fSHans Rosenfeld struct { 464*ecee5a1fSHans Rosenfeld uint16_t tt_tmpth; /* Temperature Threshold */ 465*ecee5a1fSHans Rosenfeld uint16_t tt_rsvd; 466*ecee5a1fSHans Rosenfeld } b; 467*ecee5a1fSHans Rosenfeld uint32_t r; 468*ecee5a1fSHans Rosenfeld } nvme_temp_threshold_t; 469*ecee5a1fSHans Rosenfeld 470*ecee5a1fSHans Rosenfeld /* Error Recovery Feature */ 471*ecee5a1fSHans Rosenfeld typedef union { 472*ecee5a1fSHans Rosenfeld struct { 473*ecee5a1fSHans Rosenfeld uint16_t er_tler; /* Time-Limited Error Recovery */ 474*ecee5a1fSHans Rosenfeld uint16_t er_rsvd; 475*ecee5a1fSHans Rosenfeld } b; 476*ecee5a1fSHans Rosenfeld uint32_t r; 477*ecee5a1fSHans Rosenfeld } nvme_error_recovery_t; 478*ecee5a1fSHans Rosenfeld 479*ecee5a1fSHans Rosenfeld /* Volatile Write Cache Feature */ 480*ecee5a1fSHans Rosenfeld typedef union { 481*ecee5a1fSHans Rosenfeld struct { 482*ecee5a1fSHans Rosenfeld uint32_t wc_wce:1; /* Volatile Write Cache Enable */ 483*ecee5a1fSHans Rosenfeld uint32_t wc_rsvd:31; 484*ecee5a1fSHans Rosenfeld } b; 485*ecee5a1fSHans Rosenfeld uint32_t r; 486*ecee5a1fSHans Rosenfeld } nvme_write_cache_t; 487*ecee5a1fSHans Rosenfeld 488*ecee5a1fSHans Rosenfeld /* Number of Queues Feature */ 489*ecee5a1fSHans Rosenfeld typedef union { 490*ecee5a1fSHans Rosenfeld struct { 491*ecee5a1fSHans Rosenfeld uint16_t nq_nsq; /* Number of Submission Queues */ 492*ecee5a1fSHans Rosenfeld uint16_t nq_ncq; /* Number of Completion Queues */ 493*ecee5a1fSHans Rosenfeld } b; 494*ecee5a1fSHans Rosenfeld uint32_t r; 495*ecee5a1fSHans Rosenfeld } nvme_nqueues_t; 496*ecee5a1fSHans Rosenfeld 497*ecee5a1fSHans Rosenfeld /* Interrupt Coalescing Feature */ 498*ecee5a1fSHans Rosenfeld typedef union { 499*ecee5a1fSHans Rosenfeld struct { 500*ecee5a1fSHans Rosenfeld uint8_t ic_thr; /* Aggregation Threshold */ 501*ecee5a1fSHans Rosenfeld uint8_t ic_time; /* Aggregation Time */ 502*ecee5a1fSHans Rosenfeld uint16_t ic_rsvd; 503*ecee5a1fSHans Rosenfeld } b; 504*ecee5a1fSHans Rosenfeld uint32_t r; 505*ecee5a1fSHans Rosenfeld } nvme_intr_coal_t; 506*ecee5a1fSHans Rosenfeld 507*ecee5a1fSHans Rosenfeld /* Interrupt Configuration Features */ 508*ecee5a1fSHans Rosenfeld typedef union { 509*ecee5a1fSHans Rosenfeld struct { 510*ecee5a1fSHans Rosenfeld uint16_t iv_iv; /* Interrupt Vector */ 511*ecee5a1fSHans Rosenfeld uint16_t iv_cd:1; /* Coalescing Disable */ 512*ecee5a1fSHans Rosenfeld uint16_t iv_rsvd:15; 513*ecee5a1fSHans Rosenfeld } b; 514*ecee5a1fSHans Rosenfeld uint32_t r; 515*ecee5a1fSHans Rosenfeld } nvme_intr_vect_t; 516*ecee5a1fSHans Rosenfeld 517*ecee5a1fSHans Rosenfeld /* Write Atomicity Feature */ 518*ecee5a1fSHans Rosenfeld typedef union { 519*ecee5a1fSHans Rosenfeld struct { 520*ecee5a1fSHans Rosenfeld uint32_t wa_dn:1; /* Disable Normal */ 521*ecee5a1fSHans Rosenfeld uint32_t wa_rsvd:31; 522*ecee5a1fSHans Rosenfeld } b; 523*ecee5a1fSHans Rosenfeld uint32_t r; 524*ecee5a1fSHans Rosenfeld } nvme_write_atomicity_t; 525*ecee5a1fSHans Rosenfeld 526*ecee5a1fSHans Rosenfeld /* Asynchronous Event Configuration Feature */ 527*ecee5a1fSHans Rosenfeld typedef union { 528*ecee5a1fSHans Rosenfeld struct { 529*ecee5a1fSHans Rosenfeld uint8_t aec_avail:1; /* available space too low */ 530*ecee5a1fSHans Rosenfeld uint8_t aec_temp:1; /* temperature too high */ 531*ecee5a1fSHans Rosenfeld uint8_t aec_reliab:1; /* degraded reliability */ 532*ecee5a1fSHans Rosenfeld uint8_t aec_readonly:1; /* media is read-only */ 533*ecee5a1fSHans Rosenfeld uint8_t aec_volatile:1; /* volatile memory backup failed */ 534*ecee5a1fSHans Rosenfeld uint8_t aec_rsvd1:3; 535*ecee5a1fSHans Rosenfeld uint8_t aec_rsvd2[3]; 536*ecee5a1fSHans Rosenfeld } b; 537*ecee5a1fSHans Rosenfeld uint32_t r; 538*ecee5a1fSHans Rosenfeld } nvme_async_event_conf_t; 539*ecee5a1fSHans Rosenfeld 540*ecee5a1fSHans Rosenfeld /* Autonomous Power State Transition Feature (1.1) */ 541*ecee5a1fSHans Rosenfeld typedef union { 542*ecee5a1fSHans Rosenfeld struct { 543*ecee5a1fSHans Rosenfeld uint8_t apst_apste:1; /* APST enabled */ 544*ecee5a1fSHans Rosenfeld uint8_t apst_rsvd:7; 545*ecee5a1fSHans Rosenfeld } b; 546*ecee5a1fSHans Rosenfeld uint8_t r; 547*ecee5a1fSHans Rosenfeld } nvme_auto_power_state_trans_t; 548*ecee5a1fSHans Rosenfeld 549*ecee5a1fSHans Rosenfeld typedef struct { 550*ecee5a1fSHans Rosenfeld uint32_t apst_rsvd1:3; 551*ecee5a1fSHans Rosenfeld uint32_t apst_itps:5; /* Idle Transition Power State */ 552*ecee5a1fSHans Rosenfeld uint32_t apst_itpt:24; /* Idle Time Prior to Transition */ 553*ecee5a1fSHans Rosenfeld uint32_t apst_rsvd2; 554*ecee5a1fSHans Rosenfeld } nvme_auto_power_state_t; 555*ecee5a1fSHans Rosenfeld 556*ecee5a1fSHans Rosenfeld #define NVME_AUTO_PST_BUFSIZE 256 557*ecee5a1fSHans Rosenfeld 558*ecee5a1fSHans Rosenfeld /* Software Progress Marker Feature */ 559*ecee5a1fSHans Rosenfeld typedef union { 560*ecee5a1fSHans Rosenfeld struct { 561*ecee5a1fSHans Rosenfeld uint8_t spm_pbslc; /* Pre-Boot Software Load Count */ 562*ecee5a1fSHans Rosenfeld uint8_t spm_rsvd[3]; 563*ecee5a1fSHans Rosenfeld } b; 564*ecee5a1fSHans Rosenfeld uint32_t r; 565*ecee5a1fSHans Rosenfeld } nvme_software_progress_marker_t; 566*ecee5a1fSHans Rosenfeld 567*ecee5a1fSHans Rosenfeld #pragma pack() /* pack(1) */ 568*ecee5a1fSHans Rosenfeld 569*ecee5a1fSHans Rosenfeld 570*ecee5a1fSHans Rosenfeld #ifdef __cplusplus 571*ecee5a1fSHans Rosenfeld } 572*ecee5a1fSHans Rosenfeld #endif 573*ecee5a1fSHans Rosenfeld 574*ecee5a1fSHans Rosenfeld #endif /* _SYS_NVME_H */ 575