13c9168faSHans Rosenfeld /* 23c9168faSHans Rosenfeld * This file and its contents are supplied under the terms of the 33c9168faSHans Rosenfeld * Common Development and Distribution License ("CDDL"), version 1.0. 43c9168faSHans Rosenfeld * You may only use this file in accordance with the terms of version 53c9168faSHans Rosenfeld * 1.0 of the CDDL. 63c9168faSHans Rosenfeld * 73c9168faSHans Rosenfeld * A full copy of the text of the CDDL should have accompanied this 83c9168faSHans Rosenfeld * source. A copy of the CDDL is also available via the Internet at 93c9168faSHans Rosenfeld * http://www.illumos.org/license/CDDL. 103c9168faSHans Rosenfeld */ 113c9168faSHans Rosenfeld 123c9168faSHans Rosenfeld /* 1337774c1bSHans Rosenfeld * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 14*1188b159SRobert Mustacchi * Copyright (c) 2018, Joyent, Inc. 153c9168faSHans Rosenfeld */ 163c9168faSHans Rosenfeld 173c9168faSHans Rosenfeld /* 183c9168faSHans Rosenfeld * NVMe hardware interface 193c9168faSHans Rosenfeld */ 203c9168faSHans Rosenfeld 213c9168faSHans Rosenfeld #ifndef _NVME_REG_H 223c9168faSHans Rosenfeld #define _NVME_REG_H 233c9168faSHans Rosenfeld 24ecee5a1fSHans Rosenfeld #include <sys/nvme.h> 25ecee5a1fSHans Rosenfeld 263c9168faSHans Rosenfeld #pragma pack(1) 273c9168faSHans Rosenfeld 283c9168faSHans Rosenfeld #ifdef __cplusplus 293c9168faSHans Rosenfeld extern "C" { 303c9168faSHans Rosenfeld #endif 313c9168faSHans Rosenfeld 323c9168faSHans Rosenfeld 333c9168faSHans Rosenfeld /* 343c9168faSHans Rosenfeld * NVMe constants 353c9168faSHans Rosenfeld */ 363c9168faSHans Rosenfeld #define NVME_MAX_ADMIN_QUEUE_LEN 4096 373c9168faSHans Rosenfeld 383c9168faSHans Rosenfeld /* 393c9168faSHans Rosenfeld * NVMe registers and register fields 403c9168faSHans Rosenfeld */ 413c9168faSHans Rosenfeld #define NVME_REG_CAP 0x0 /* Controller Capabilities */ 423c9168faSHans Rosenfeld #define NVME_REG_VS 0x8 /* Version */ 433c9168faSHans Rosenfeld #define NVME_REG_INTMS 0xc /* Interrupt Mask Set */ 443c9168faSHans Rosenfeld #define NVME_REG_INTMC 0x10 /* Interrupt Mask Clear */ 453c9168faSHans Rosenfeld #define NVME_REG_CC 0x14 /* Controller Configuration */ 463c9168faSHans Rosenfeld #define NVME_REG_CSTS 0x1c /* Controller Status */ 473c9168faSHans Rosenfeld #define NVME_REG_NSSR 0x20 /* NVM Subsystem Reset */ 483c9168faSHans Rosenfeld #define NVME_REG_AQA 0x24 /* Admin Queue Attributes */ 493c9168faSHans Rosenfeld #define NVME_REG_ASQ 0x28 /* Admin Submission Queue */ 503c9168faSHans Rosenfeld #define NVME_REG_ACQ 0x30 /* Admin Completion Qeueu */ 51*1188b159SRobert Mustacchi #define NVME_REG_CMBLOC 0x38 /* Controller Memory Buffer Location */ 52*1188b159SRobert Mustacchi #define NVME_REG_CMBSZ 0x3C /* Controller Memory Buffer Size */ 53*1188b159SRobert Mustacchi #define NVME_REG_BPINFO 0x40 /* Boot Partition Information */ 54*1188b159SRobert Mustacchi #define NVME_REG_BPRSEL 0x44 /* Boot Partition Read Select */ 55*1188b159SRobert Mustacchi #define NVME_REG_BPMBL 0x48 /* Boot Partition Memory Buffer Loc */ 563c9168faSHans Rosenfeld #define NVME_REG_SQTDBL(nvme, n) \ 573c9168faSHans Rosenfeld (0x1000 + ((2 * (n)) * nvme->n_doorbell_stride)) 583c9168faSHans Rosenfeld #define NVME_REG_CQHDBL(nvme, n) \ 593c9168faSHans Rosenfeld (0x1000 + ((2 * (n) + 1) * nvme->n_doorbell_stride)) 603c9168faSHans Rosenfeld 613c9168faSHans Rosenfeld #define NVME_CAP_CSS_NVM 1 /* NVM Command Set */ 623c9168faSHans Rosenfeld #define NVME_CAP_AMS_WRR 1 /* Weighted Round-Robin */ 633c9168faSHans Rosenfeld 643c9168faSHans Rosenfeld /* CAP -- Controller Capabilities */ 653c9168faSHans Rosenfeld typedef union { 663c9168faSHans Rosenfeld struct { 673c9168faSHans Rosenfeld uint16_t cap_mqes; /* Maximum Queue Entries Supported */ 683c9168faSHans Rosenfeld uint8_t cap_cqr:1; /* Contiguous Queues Required */ 693c9168faSHans Rosenfeld uint8_t cap_ams:2; /* Arbitration Mechanisms Supported */ 703c9168faSHans Rosenfeld uint8_t cap_rsvd1:5; 713c9168faSHans Rosenfeld uint8_t cap_to; /* Timeout */ 723c9168faSHans Rosenfeld uint16_t cap_dstrd:4; /* Doorbell Stride */ 733c9168faSHans Rosenfeld uint16_t cap_nssrs:1; /* NVM Subsystem Reset Supported */ 743c9168faSHans Rosenfeld uint16_t cap_css:8; /* Command Sets Supported */ 75*1188b159SRobert Mustacchi uint16_t cap_rsvd2:2; 76*1188b159SRobert Mustacchi uint8_t cap_bps:1; /* Boot Partition Support */ 773c9168faSHans Rosenfeld uint8_t cap_mpsmin:4; /* Memory Page Size Minimum */ 783c9168faSHans Rosenfeld uint8_t cap_mpsmax:4; /* Memory Page Size Maximum */ 793c9168faSHans Rosenfeld uint8_t cap_rsvd3; 803c9168faSHans Rosenfeld } b; 813c9168faSHans Rosenfeld uint64_t r; 823c9168faSHans Rosenfeld } nvme_reg_cap_t; 833c9168faSHans Rosenfeld 843c9168faSHans Rosenfeld /* VS -- Version */ 853c9168faSHans Rosenfeld typedef union { 863c9168faSHans Rosenfeld struct { 873c9168faSHans Rosenfeld uint8_t vs_rsvd; 883c9168faSHans Rosenfeld uint8_t vs_mnr; /* Minor Version Number */ 893c9168faSHans Rosenfeld uint16_t vs_mjr; /* Major Version Number */ 903c9168faSHans Rosenfeld } b; 913c9168faSHans Rosenfeld uint32_t r; 923c9168faSHans Rosenfeld } nvme_reg_vs_t; 933c9168faSHans Rosenfeld 943c9168faSHans Rosenfeld /* CC -- Controller Configuration */ 953c9168faSHans Rosenfeld #define NVME_CC_SHN_NORMAL 1 /* Normal Shutdown Notification */ 963c9168faSHans Rosenfeld #define NVME_CC_SHN_ABRUPT 2 /* Abrupt Shutdown Notification */ 973c9168faSHans Rosenfeld 983c9168faSHans Rosenfeld typedef union { 993c9168faSHans Rosenfeld struct { 1003c9168faSHans Rosenfeld uint16_t cc_en:1; /* Enable */ 1013c9168faSHans Rosenfeld uint16_t cc_rsvd1:3; 1023c9168faSHans Rosenfeld uint16_t cc_css:3; /* I/O Command Set Selected */ 1033c9168faSHans Rosenfeld uint16_t cc_mps:4; /* Memory Page Size */ 1043c9168faSHans Rosenfeld uint16_t cc_ams:3; /* Arbitration Mechanism Selected */ 1053c9168faSHans Rosenfeld uint16_t cc_shn:2; /* Shutdown Notification */ 1063c9168faSHans Rosenfeld uint8_t cc_iosqes:4; /* I/O Submission Queue Entry Size */ 1073c9168faSHans Rosenfeld uint8_t cc_iocqes:4; /* I/O Completion Queue Entry Size */ 1083c9168faSHans Rosenfeld uint8_t cc_rsvd2; 1093c9168faSHans Rosenfeld } b; 1103c9168faSHans Rosenfeld uint32_t r; 1113c9168faSHans Rosenfeld } nvme_reg_cc_t; 1123c9168faSHans Rosenfeld 1133c9168faSHans Rosenfeld /* CSTS -- Controller Status */ 1143c9168faSHans Rosenfeld #define NVME_CSTS_SHN_OCCURING 1 /* Shutdown Processing Occuring */ 1153c9168faSHans Rosenfeld #define NVME_CSTS_SHN_COMPLETE 2 /* Shutdown Processing Complete */ 1163c9168faSHans Rosenfeld 1173c9168faSHans Rosenfeld typedef union { 1183c9168faSHans Rosenfeld struct { 1193c9168faSHans Rosenfeld uint32_t csts_rdy:1; /* Ready */ 1203c9168faSHans Rosenfeld uint32_t csts_cfs:1; /* Controller Fatal Status */ 1213c9168faSHans Rosenfeld uint32_t csts_shst:2; /* Shutdown Status */ 1223c9168faSHans Rosenfeld uint32_t csts_nssro:1; /* NVM Subsystem Reset Occured */ 123*1188b159SRobert Mustacchi uint32_t csts_pp:1; /* Processing Paused */ 124*1188b159SRobert Mustacchi uint32_t csts_rsvd:26; 1253c9168faSHans Rosenfeld } b; 1263c9168faSHans Rosenfeld uint32_t r; 1273c9168faSHans Rosenfeld } nvme_reg_csts_t; 1283c9168faSHans Rosenfeld 1293c9168faSHans Rosenfeld /* NSSR -- NVM Subsystem Reset */ 1303c9168faSHans Rosenfeld #define NVME_NSSR_NSSRC 0x4e564d65 /* NSSR magic value */ 1313c9168faSHans Rosenfeld typedef uint32_t nvme_reg_nssr_t; 1323c9168faSHans Rosenfeld 1333c9168faSHans Rosenfeld /* AQA -- Admin Queue Attributes */ 1343c9168faSHans Rosenfeld typedef union { 1353c9168faSHans Rosenfeld struct { 1363c9168faSHans Rosenfeld uint16_t aqa_asqs:12; /* Admin Submission Queue Size */ 1373c9168faSHans Rosenfeld uint16_t aqa_rsvd1:4; 1383c9168faSHans Rosenfeld uint16_t aqa_acqs:12; /* Admin Completion Queue Size */ 1393c9168faSHans Rosenfeld uint16_t aqa_rsvd2:4; 1403c9168faSHans Rosenfeld } b; 1413c9168faSHans Rosenfeld uint32_t r; 1423c9168faSHans Rosenfeld } nvme_reg_aqa_t; 1433c9168faSHans Rosenfeld 1443c9168faSHans Rosenfeld /* 1453c9168faSHans Rosenfeld * The spec specifies the lower 12 bits of ASQ and ACQ as reserved, which is 1463c9168faSHans Rosenfeld * probably a specification bug. The full 64bit regs are used as base address, 1473c9168faSHans Rosenfeld * and the lower bits must be zero to ensure alignment on the page size 1483c9168faSHans Rosenfeld * specified in CC.MPS. 1493c9168faSHans Rosenfeld */ 1503c9168faSHans Rosenfeld /* ASQ -- Admin Submission Queue Base Address */ 1513c9168faSHans Rosenfeld typedef uint64_t nvme_reg_asq_t; /* Admin Submission Queue Base */ 1523c9168faSHans Rosenfeld 1533c9168faSHans Rosenfeld /* ACQ -- Admin Completion Queue Base Address */ 1543c9168faSHans Rosenfeld typedef uint64_t nvme_reg_acq_t; /* Admin Completion Queue Base */ 1553c9168faSHans Rosenfeld 156*1188b159SRobert Mustacchi /* CMBLOC - Controller Memory Buffer Location */ 157*1188b159SRobert Mustacchi typedef union { 158*1188b159SRobert Mustacchi struct { 159*1188b159SRobert Mustacchi uint32_t cmbloc_bir:3; /* Base Indicator Register */ 160*1188b159SRobert Mustacchi uint32_t cmbloc_rsvd:9; 161*1188b159SRobert Mustacchi uint32_t cmbloc_ofst:20; /* Offset */ 162*1188b159SRobert Mustacchi } b; 163*1188b159SRobert Mustacchi uint32_t r; 164*1188b159SRobert Mustacchi } nvme_reg_cmbloc_t; 165*1188b159SRobert Mustacchi 166*1188b159SRobert Mustacchi /* CMBSZ - Controller Memory Buffer Size */ 167*1188b159SRobert Mustacchi typedef union { 168*1188b159SRobert Mustacchi struct { 169*1188b159SRobert Mustacchi uint32_t cmbsz_sqs:1; /* Submission Queue Support */ 170*1188b159SRobert Mustacchi uint32_t cmbsz_cqs:1; /* Completion Queue Support */ 171*1188b159SRobert Mustacchi uint32_t cmbsz_lists:1; /* PRP SGL List Support */ 172*1188b159SRobert Mustacchi uint32_t cmbsz_rds:1; /* Read Data Support */ 173*1188b159SRobert Mustacchi uint32_t cmbsz_wds:1; /* Write Data Support */ 174*1188b159SRobert Mustacchi uint32_t cmbsz_rsvd:3; 175*1188b159SRobert Mustacchi uint32_t cmbsz_szu:4; /* Size Units */ 176*1188b159SRobert Mustacchi uint32_t cmbsz_sz:20; /* Size */ 177*1188b159SRobert Mustacchi } b; 178*1188b159SRobert Mustacchi uint32_t r; 179*1188b159SRobert Mustacchi } nvme_reg_cmbsz_t; 180*1188b159SRobert Mustacchi 181*1188b159SRobert Mustacchi /* BPINFO - Boot Partition Information */ 182*1188b159SRobert Mustacchi typedef union { 183*1188b159SRobert Mustacchi struct { 184*1188b159SRobert Mustacchi uint32_t bpinfo_bpsz:15; /* Boot Partition Size */ 185*1188b159SRobert Mustacchi uint32_t bpinfo_rsvd:9; 186*1188b159SRobert Mustacchi uint32_t bpinfo_brs:2; /* Boot Read Status */ 187*1188b159SRobert Mustacchi uint32_t bpinfo_rsvd2:5; 188*1188b159SRobert Mustacchi uint32_t bpinfo_abpid:1; /* Active Boot Partition ID */ 189*1188b159SRobert Mustacchi } b; 190*1188b159SRobert Mustacchi uint32_t r; 191*1188b159SRobert Mustacchi } nvme_reg_bpinfo_t; 192*1188b159SRobert Mustacchi 193*1188b159SRobert Mustacchi /* BPRSEL - Boot Partition Read Select */ 194*1188b159SRobert Mustacchi typedef union { 195*1188b159SRobert Mustacchi struct { 196*1188b159SRobert Mustacchi uint32_t bprsel_bprsz:10; /* Boot Partition Read Size */ 197*1188b159SRobert Mustacchi uint32_t bprsel_bprof:20; /* Boot Partition Read Offset */ 198*1188b159SRobert Mustacchi uint32_t bprsel_rsvd:1; 199*1188b159SRobert Mustacchi uint32_t bprsel_bpid:1; /* Boot Partition Identifier */ 200*1188b159SRobert Mustacchi } b; 201*1188b159SRobert Mustacchi uint32_t r; 202*1188b159SRobert Mustacchi } nvme_reg_bprsel_t; 203*1188b159SRobert Mustacchi 204*1188b159SRobert Mustacchi /* BPMBL - Boot Partition Memory Location Buffer Location */ 205*1188b159SRobert Mustacchi typedef uint64_t nvme_reg_bpbml_t; /* Memory Buffer Base Address */ 206*1188b159SRobert Mustacchi 2073c9168faSHans Rosenfeld /* SQyTDBL -- Submission Queue y Tail Doorbell */ 2083c9168faSHans Rosenfeld typedef union { 2093c9168faSHans Rosenfeld struct { 2103c9168faSHans Rosenfeld uint16_t sqtdbl_sqt; /* Submission Queue Tail */ 2113c9168faSHans Rosenfeld uint16_t sqtdbl_rsvd; 2123c9168faSHans Rosenfeld } b; 2133c9168faSHans Rosenfeld uint32_t r; 2143c9168faSHans Rosenfeld } nvme_reg_sqtdbl_t; 2153c9168faSHans Rosenfeld 2163c9168faSHans Rosenfeld /* CQyHDBL -- Completion Queue y Head Doorbell */ 2173c9168faSHans Rosenfeld typedef union { 2183c9168faSHans Rosenfeld struct { 2193c9168faSHans Rosenfeld uint16_t cqhdbl_cqh; /* Completion Queue Head */ 2203c9168faSHans Rosenfeld uint16_t cqhdbl_rsvd; 2213c9168faSHans Rosenfeld } b; 2223c9168faSHans Rosenfeld uint32_t r; 2233c9168faSHans Rosenfeld } nvme_reg_cqhdbl_t; 2243c9168faSHans Rosenfeld 2253c9168faSHans Rosenfeld /* 2263c9168faSHans Rosenfeld * NVMe submission queue entries 2273c9168faSHans Rosenfeld */ 2283c9168faSHans Rosenfeld 2293c9168faSHans Rosenfeld /* NVMe scatter/gather list descriptor */ 2303c9168faSHans Rosenfeld typedef struct { 2313c9168faSHans Rosenfeld uint64_t sgl_addr; /* Address */ 2323c9168faSHans Rosenfeld uint32_t sgl_len; /* Length */ 2333c9168faSHans Rosenfeld uint8_t sgl_rsvd[3]; 2343c9168faSHans Rosenfeld uint8_t sgl_zero:4; 2353c9168faSHans Rosenfeld uint8_t sgl_type:4; /* SGL descriptor type */ 2363c9168faSHans Rosenfeld } nvme_sgl_t; 2373c9168faSHans Rosenfeld 2383c9168faSHans Rosenfeld /* NVMe SGL descriptor type */ 2393c9168faSHans Rosenfeld #define NVME_SGL_DATA_BLOCK 0 2403c9168faSHans Rosenfeld #define NVME_SGL_BIT_BUCKET 1 2413c9168faSHans Rosenfeld #define NVME_SGL_SEGMENT 2 2423c9168faSHans Rosenfeld #define NVME_SGL_LAST_SEGMENT 3 2433c9168faSHans Rosenfeld #define NVME_SGL_VENDOR 0xf 2443c9168faSHans Rosenfeld 2453c9168faSHans Rosenfeld /* NVMe submission queue entry */ 2463c9168faSHans Rosenfeld typedef struct { 2473c9168faSHans Rosenfeld uint8_t sqe_opc; /* Opcode */ 2483c9168faSHans Rosenfeld uint8_t sqe_fuse:2; /* Fused Operation */ 2493c9168faSHans Rosenfeld uint8_t sqe_rsvd:5; 2503c9168faSHans Rosenfeld uint8_t sqe_psdt:1; /* PRP or SGL for Data Transfer */ 2513c9168faSHans Rosenfeld uint16_t sqe_cid; /* Command Identifier */ 2523c9168faSHans Rosenfeld uint32_t sqe_nsid; /* Namespace Identifier */ 2533c9168faSHans Rosenfeld uint64_t sqe_rsvd1; 2543c9168faSHans Rosenfeld union { 2553c9168faSHans Rosenfeld uint64_t m_ptr; /* Metadata Pointer */ 2563c9168faSHans Rosenfeld uint64_t m_sglp; /* Metadata SGL Segment Pointer */ 2573c9168faSHans Rosenfeld } sqe_m; 2583c9168faSHans Rosenfeld union { 2593c9168faSHans Rosenfeld uint64_t d_prp[2]; /* Physical Page Region Entries 1 & 2 */ 2603c9168faSHans Rosenfeld nvme_sgl_t d_sgl; /* SGL Entry 1 */ 2613c9168faSHans Rosenfeld } sqe_dptr; /* Data Pointer */ 2623c9168faSHans Rosenfeld uint32_t sqe_cdw10; /* Number of Dwords in Data Transfer */ 2633c9168faSHans Rosenfeld uint32_t sqe_cdw11; /* Number of Dwords in Metadata Xfer */ 2643c9168faSHans Rosenfeld uint32_t sqe_cdw12; 2653c9168faSHans Rosenfeld uint32_t sqe_cdw13; 2663c9168faSHans Rosenfeld uint32_t sqe_cdw14; 2673c9168faSHans Rosenfeld uint32_t sqe_cdw15; 2683c9168faSHans Rosenfeld } nvme_sqe_t; 2693c9168faSHans Rosenfeld 2703c9168faSHans Rosenfeld /* NVMe admin command opcodes */ 2713c9168faSHans Rosenfeld #define NVME_OPC_DELETE_SQUEUE 0x0 2723c9168faSHans Rosenfeld #define NVME_OPC_CREATE_SQUEUE 0x1 2733c9168faSHans Rosenfeld #define NVME_OPC_GET_LOG_PAGE 0x2 2743c9168faSHans Rosenfeld #define NVME_OPC_DELETE_CQUEUE 0x4 2753c9168faSHans Rosenfeld #define NVME_OPC_CREATE_CQUEUE 0x5 2763c9168faSHans Rosenfeld #define NVME_OPC_IDENTIFY 0x6 2773c9168faSHans Rosenfeld #define NVME_OPC_ABORT 0x8 2783c9168faSHans Rosenfeld #define NVME_OPC_SET_FEATURES 0x9 2793c9168faSHans Rosenfeld #define NVME_OPC_GET_FEATURES 0xa 2803c9168faSHans Rosenfeld #define NVME_OPC_ASYNC_EVENT 0xc 281*1188b159SRobert Mustacchi #define NVME_OPC_NS_MGMT 0xd /* 1.2 */ 2823c9168faSHans Rosenfeld #define NVME_OPC_FW_ACTIVATE 0x10 2833c9168faSHans Rosenfeld #define NVME_OPC_FW_IMAGE_LOAD 0x11 284*1188b159SRobert Mustacchi #define NVME_OPC_SELF_TEST 0x14 /* 1.3 */ 285*1188b159SRobert Mustacchi #define NVME_OPC_NS_ATTACH 0x15 /* 1.2 */ 286*1188b159SRobert Mustacchi #define NVME_OPC_KEEP_ALIVE 0x18 /* 1.3 */ 287*1188b159SRobert Mustacchi #define NVME_OPC_DIRECTIVE_SEND 0x19 /* 1.3 */ 288*1188b159SRobert Mustacchi #define NVME_OPC_DIRECTIVE_RECV 0x1A /* 1.3 */ 289*1188b159SRobert Mustacchi #define NVME_OPC_VIRT_MGMT 0x1C /* 1.3 */ 290*1188b159SRobert Mustacchi #define NVME_OPC_NVMEMI_SEND 0x1D /* 1.3 */ 291*1188b159SRobert Mustacchi #define NVME_OPC_NVMEMI_RECV 0x1E /* 1.3 */ 292*1188b159SRobert Mustacchi #define NVME_OPC_DB_CONFIG 0x7C /* 1.3 */ 2933c9168faSHans Rosenfeld 2943c9168faSHans Rosenfeld /* NVMe NVM command set specific admin command opcodes */ 2953c9168faSHans Rosenfeld #define NVME_OPC_NVM_FORMAT 0x80 2963c9168faSHans Rosenfeld #define NVME_OPC_NVM_SEC_SEND 0x81 2973c9168faSHans Rosenfeld #define NVME_OPC_NVM_SEC_RECV 0x82 2983c9168faSHans Rosenfeld 2993c9168faSHans Rosenfeld /* NVMe NVM command opcodes */ 3003c9168faSHans Rosenfeld #define NVME_OPC_NVM_FLUSH 0x0 3013c9168faSHans Rosenfeld #define NVME_OPC_NVM_WRITE 0x1 3023c9168faSHans Rosenfeld #define NVME_OPC_NVM_READ 0x2 3033c9168faSHans Rosenfeld #define NVME_OPC_NVM_WRITE_UNC 0x4 3043c9168faSHans Rosenfeld #define NVME_OPC_NVM_COMPARE 0x5 3053c9168faSHans Rosenfeld #define NVME_OPC_NVM_WRITE_ZERO 0x8 3063c9168faSHans Rosenfeld #define NVME_OPC_NVM_DSET_MGMT 0x9 3073c9168faSHans Rosenfeld #define NVME_OPC_NVM_RESV_REG 0xd 3083c9168faSHans Rosenfeld #define NVME_OPC_NVM_RESV_REPRT 0xe 3093c9168faSHans Rosenfeld #define NVME_OPC_NVM_RESV_ACQ 0x11 3103c9168faSHans Rosenfeld #define NVME_OPC_NVM_RESV_REL 0x12 3113c9168faSHans Rosenfeld 3123c9168faSHans Rosenfeld /* 3133c9168faSHans Rosenfeld * NVMe completion queue entry 3143c9168faSHans Rosenfeld */ 3153c9168faSHans Rosenfeld typedef struct { 3163c9168faSHans Rosenfeld uint32_t cqe_dw0; /* Command Specific */ 3173c9168faSHans Rosenfeld uint32_t cqe_rsvd1; 3183c9168faSHans Rosenfeld uint16_t cqe_sqhd; /* SQ Head Pointer */ 3193c9168faSHans Rosenfeld uint16_t cqe_sqid; /* SQ Identifier */ 3203c9168faSHans Rosenfeld uint16_t cqe_cid; /* Command Identifier */ 3213c9168faSHans Rosenfeld nvme_cqe_sf_t cqe_sf; /* Status Field */ 3223c9168faSHans Rosenfeld } nvme_cqe_t; 3233c9168faSHans Rosenfeld 3243c9168faSHans Rosenfeld /* NVMe completion status code type */ 3253c9168faSHans Rosenfeld #define NVME_CQE_SCT_GENERIC 0 /* Generic Command Status */ 3263c9168faSHans Rosenfeld #define NVME_CQE_SCT_SPECIFIC 1 /* Command Specific Status */ 3273c9168faSHans Rosenfeld #define NVME_CQE_SCT_INTEGRITY 2 /* Media and Data Integrity Errors */ 3283c9168faSHans Rosenfeld #define NVME_CQE_SCT_VENDOR 7 /* Vendor Specific */ 3293c9168faSHans Rosenfeld 3303c9168faSHans Rosenfeld /* NVMe completion status code (generic) */ 3313c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_SUCCESS 0x0 /* Successful Completion */ 3323c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_OPC 0x1 /* Invalid Command Opcode */ 3333c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_FLD 0x2 /* Invalid Field in Command */ 3343c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_ID_CNFL 0x3 /* Command ID Conflict */ 3353c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_DATA_XFR_ERR 0x4 /* Data Transfer Error */ 3363c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_ABORT_PWRLOSS 0x5 /* Cmds Aborted / Pwr Loss */ 3373c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INTERNAL_ERR 0x6 /* Internal Error */ 3383c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_ABORT_REQUEST 0x7 /* Command Abort Requested */ 3393c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_ABORT_SQ_DEL 0x8 /* Cmd Aborted / SQ deletion */ 3403c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_ABORT_FUSE_FAIL 0x9 /* Cmd Aborted / Failed Fused */ 3413c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_ABORT_FUSE_MISS 0xa /* Cmd Aborted / Missing Fusd */ 3423c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_NS 0xb /* Inval Namespace or Format */ 3433c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_CMD_SEQ_ERR 0xc /* Command Sequence Error */ 3443c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_SGL_LAST 0xd /* Inval SGL Last Seg Desc */ 3453c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_SGL_NUM 0xe /* Inval Number of SGL Desc */ 3463c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_DSGL_LEN 0xf /* Data SGL Length Invalid */ 3473c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_MSGL_LEN 0x10 /* Metadata SGL Length Inval */ 3483c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_INV_SGL_DESC 0x11 /* SGL Descriptor Type Inval */ 3493c9168faSHans Rosenfeld 3503c9168faSHans Rosenfeld /* NVMe completion status code (generic NVM commands) */ 3513c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_NVM_LBA_RANGE 0x80 /* LBA Out Of Range */ 3523c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_NVM_CAP_EXC 0x81 /* Capacity Exceeded */ 3533c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_NVM_NS_NOTRDY 0x82 /* Namespace Not Ready */ 3543c9168faSHans Rosenfeld #define NVME_CQE_SC_GEN_NVM_RSV_CNFLCT 0x83 /* Reservation Conflict */ 3553c9168faSHans Rosenfeld 3563c9168faSHans Rosenfeld /* NVMe completion status code (command specific) */ 3573c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_CQ 0x0 /* Completion Queue Invalid */ 3583c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_QID 0x1 /* Invalid Queue Identifier */ 3593c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_MAX_QSZ_EXC 0x2 /* Max Queue Size Exceeded */ 3603c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_ABRT_CMD_EXC 0x3 /* Abort Cmd Limit Exceeded */ 3613c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_ASYNC_EVREQ_EXC 0x5 /* Async Event Request Limit */ 3623c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_FW_SLOT 0x6 /* Invalid Firmware Slot */ 3633c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_FW_IMG 0x7 /* Invalid Firmware Image */ 3643c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_INT_VECT 0x8 /* Invalid Interrupt Vector */ 3653c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_LOG_PAGE 0x9 /* Invalid Log Page */ 3663c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_FORMAT 0xa /* Invalid Format */ 3673c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_FW_RESET 0xb /* FW Application Reset Reqd */ 3683c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_INV_Q_DEL 0xc /* Invalid Queue Deletion */ 3693c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_FEAT_SAVE 0xd /* Feature Id Not Saveable */ 3703c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_FEAT_CHG 0xe /* Feature Not Changeable */ 3713c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_FEAT_NS_SPEC 0xf /* Feature Not Namespace Spec */ 3723c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_FW_NSSR 0x10 /* FW Application NSSR Reqd */ 3733c9168faSHans Rosenfeld 3743c9168faSHans Rosenfeld /* NVMe completion status code (NVM command specific */ 3753c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_NVM_CNFL_ATTR 0x80 /* Conflicting Attributes */ 3763c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_NVM_INV_PROT 0x81 /* Invalid Protection */ 3773c9168faSHans Rosenfeld #define NVME_CQE_SC_SPC_NVM_READONLY 0x82 /* Write to Read Only Range */ 3783c9168faSHans Rosenfeld 3793c9168faSHans Rosenfeld /* NVMe completion status code (data / metadata integrity) */ 3803c9168faSHans Rosenfeld #define NVME_CQE_SC_INT_NVM_WRITE 0x80 /* Write Fault */ 3813c9168faSHans Rosenfeld #define NVME_CQE_SC_INT_NVM_READ 0x81 /* Unrecovered Read Error */ 3823c9168faSHans Rosenfeld #define NVME_CQE_SC_INT_NVM_GUARD 0x82 /* Guard Check Error */ 3833c9168faSHans Rosenfeld #define NVME_CQE_SC_INT_NVM_APPL_TAG 0x83 /* Application Tag Check Err */ 3843c9168faSHans Rosenfeld #define NVME_CQE_SC_INT_NVM_REF_TAG 0x84 /* Reference Tag Check Err */ 3853c9168faSHans Rosenfeld #define NVME_CQE_SC_INT_NVM_COMPARE 0x85 /* Compare Failure */ 3863c9168faSHans Rosenfeld #define NVME_CQE_SC_INT_NVM_ACCESS 0x86 /* Access Denied */ 3873c9168faSHans Rosenfeld 3883c9168faSHans Rosenfeld /* 3893c9168faSHans Rosenfeld * NVMe Asynchronous Event Request 3903c9168faSHans Rosenfeld */ 3913c9168faSHans Rosenfeld #define NVME_ASYNC_TYPE_ERROR 0x0 /* Error Status */ 3923c9168faSHans Rosenfeld #define NVME_ASYNC_TYPE_HEALTH 0x1 /* SMART/Health Status */ 3933c9168faSHans Rosenfeld #define NVME_ASYNC_TYPE_VENDOR 0x7 /* vendor specific */ 3943c9168faSHans Rosenfeld 3953c9168faSHans Rosenfeld #define NVME_ASYNC_ERROR_INV_SQ 0x0 /* Invalid Submission Queue */ 3963c9168faSHans Rosenfeld #define NVME_ASYNC_ERROR_INV_DBL 0x1 /* Invalid Doorbell Write */ 3973c9168faSHans Rosenfeld #define NVME_ASYNC_ERROR_DIAGFAIL 0x2 /* Diagnostic Failure */ 3983c9168faSHans Rosenfeld #define NVME_ASYNC_ERROR_PERSISTENT 0x3 /* Persistent Internal Error */ 3993c9168faSHans Rosenfeld #define NVME_ASYNC_ERROR_TRANSIENT 0x4 /* Transient Internal Error */ 4003c9168faSHans Rosenfeld #define NVME_ASYNC_ERROR_FW_LOAD 0x5 /* Firmware Image Load Error */ 4013c9168faSHans Rosenfeld 4023c9168faSHans Rosenfeld #define NVME_ASYNC_HEALTH_RELIABILITY 0x0 /* Device Reliability */ 4033c9168faSHans Rosenfeld #define NVME_ASYNC_HEALTH_TEMPERATURE 0x1 /* Temp. Above Threshold */ 4043c9168faSHans Rosenfeld #define NVME_ASYNC_HEALTH_SPARE 0x2 /* Spare Below Threshold */ 4053c9168faSHans Rosenfeld 4063c9168faSHans Rosenfeld typedef union { 4073c9168faSHans Rosenfeld struct { 4083c9168faSHans Rosenfeld uint8_t ae_type:3; /* Asynchronous Event Type */ 4093c9168faSHans Rosenfeld uint8_t ae_rsvd1:5; 4103c9168faSHans Rosenfeld uint8_t ae_info; /* Asynchronous Event Info */ 4113c9168faSHans Rosenfeld uint8_t ae_logpage; /* Associated Log Page */ 4123c9168faSHans Rosenfeld uint8_t ae_rsvd2; 4133c9168faSHans Rosenfeld } b; 4143c9168faSHans Rosenfeld uint32_t r; 4153c9168faSHans Rosenfeld } nvme_async_event_t; 4163c9168faSHans Rosenfeld 4173c9168faSHans Rosenfeld /* 4183c9168faSHans Rosenfeld * NVMe Create Completion/Submission Queue 4193c9168faSHans Rosenfeld */ 4203c9168faSHans Rosenfeld typedef union { 4213c9168faSHans Rosenfeld struct { 4223c9168faSHans Rosenfeld uint16_t q_qid; /* Queue Identifier */ 4233c9168faSHans Rosenfeld uint16_t q_qsize; /* Queue Size */ 4243c9168faSHans Rosenfeld } b; 4253c9168faSHans Rosenfeld uint32_t r; 4263c9168faSHans Rosenfeld } nvme_create_queue_dw10_t; 4273c9168faSHans Rosenfeld 4283c9168faSHans Rosenfeld typedef union { 4293c9168faSHans Rosenfeld struct { 4303c9168faSHans Rosenfeld uint16_t cq_pc:1; /* Physically Contiguous */ 4313c9168faSHans Rosenfeld uint16_t cq_ien:1; /* Interrupts Enabled */ 4323c9168faSHans Rosenfeld uint16_t cq_rsvd:14; 4333c9168faSHans Rosenfeld uint16_t cq_iv; /* Interrupt Vector */ 4343c9168faSHans Rosenfeld } b; 4353c9168faSHans Rosenfeld uint32_t r; 4363c9168faSHans Rosenfeld } nvme_create_cq_dw11_t; 4373c9168faSHans Rosenfeld 4383c9168faSHans Rosenfeld typedef union { 4393c9168faSHans Rosenfeld struct { 4403c9168faSHans Rosenfeld uint16_t sq_pc:1; /* Physically Contiguous */ 4413c9168faSHans Rosenfeld uint16_t sq_qprio:2; /* Queue Priority */ 4423c9168faSHans Rosenfeld uint16_t sq_rsvd:13; 4433c9168faSHans Rosenfeld uint16_t sq_cqid; /* Completion Queue ID */ 4443c9168faSHans Rosenfeld } b; 4453c9168faSHans Rosenfeld uint32_t r; 4463c9168faSHans Rosenfeld } nvme_create_sq_dw11_t; 4473c9168faSHans Rosenfeld 4483c9168faSHans Rosenfeld /* 4493c9168faSHans Rosenfeld * NVMe Identify 4503c9168faSHans Rosenfeld */ 4513c9168faSHans Rosenfeld 4523c9168faSHans Rosenfeld /* NVMe Identify parameters (cdw10) */ 4533c9168faSHans Rosenfeld #define NVME_IDENTIFY_NSID 0x0 /* Identify Namespace */ 4543c9168faSHans Rosenfeld #define NVME_IDENTIFY_CTRL 0x1 /* Identify Controller */ 4553c9168faSHans Rosenfeld #define NVME_IDENTIFY_LIST 0x2 /* Identify List Namespaces */ 4563c9168faSHans Rosenfeld 457*1188b159SRobert Mustacchi #define NVME_IDENTIFY_NSID_ALLOC_LIST 0x10 /* List Allocated NSID */ 458*1188b159SRobert Mustacchi #define NVME_IDENTIFY_NSID_ALLOC 0x11 /* Identify Allocated NSID */ 459*1188b159SRobert Mustacchi #define NVME_IDENTIFY_NSID_CTRL_LIST 0x12 /* List Controllers on NSID */ 460*1188b159SRobert Mustacchi #define NVME_IDENTIFY_CTRL_LIST 0x13 /* Controller List */ 461*1188b159SRobert Mustacchi #define NVME_IDENTIFY_PRIMARY_CAPS 0x14 /* Primary Controller Caps */ 4623c9168faSHans Rosenfeld 4633c9168faSHans Rosenfeld /* 4643c9168faSHans Rosenfeld * NVMe Abort Command 4653c9168faSHans Rosenfeld */ 4663c9168faSHans Rosenfeld typedef union { 4673c9168faSHans Rosenfeld struct { 4683c9168faSHans Rosenfeld uint16_t ac_sqid; /* Submission Queue ID */ 4693c9168faSHans Rosenfeld uint16_t ac_cid; /* Command ID */ 4703c9168faSHans Rosenfeld } b; 4713c9168faSHans Rosenfeld uint32_t r; 4723c9168faSHans Rosenfeld } nvme_abort_cmd_t; 4733c9168faSHans Rosenfeld 4743c9168faSHans Rosenfeld 4753c9168faSHans Rosenfeld /* 4763c9168faSHans Rosenfeld * NVMe Get Log Page 4773c9168faSHans Rosenfeld */ 4783c9168faSHans Rosenfeld typedef union { 4793c9168faSHans Rosenfeld struct { 4803c9168faSHans Rosenfeld uint8_t lp_lid; /* Log Page Identifier */ 4813c9168faSHans Rosenfeld uint8_t lp_rsvd1; 4823c9168faSHans Rosenfeld uint16_t lp_numd:12; /* Number of Dwords */ 4833c9168faSHans Rosenfeld uint16_t lp_rsvd2:4; 4843c9168faSHans Rosenfeld } b; 4853c9168faSHans Rosenfeld uint32_t r; 4863c9168faSHans Rosenfeld } nvme_getlogpage_t; 4873c9168faSHans Rosenfeld 4883c9168faSHans Rosenfeld 4893c9168faSHans Rosenfeld #ifdef __cplusplus 4903c9168faSHans Rosenfeld } 4913c9168faSHans Rosenfeld #endif 4923c9168faSHans Rosenfeld 4933c9168faSHans Rosenfeld #pragma pack() /* pack(1) */ 4943c9168faSHans Rosenfeld 4953c9168faSHans Rosenfeld #endif /* _NVME_REG_H */ 496