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