The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/nvme/nvme.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (C) 2012-2013 Intel Corporation
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  *
   16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   26  * SUCH DAMAGE.
   27  *
   28  * $FreeBSD$
   29  */
   30 
   31 #ifndef __NVME_H__
   32 #define __NVME_H__
   33 
   34 #ifdef _KERNEL
   35 #include <sys/types.h>
   36 #endif
   37 
   38 #include <sys/param.h>
   39 #include <sys/endian.h>
   40 
   41 #define NVME_PASSTHROUGH_CMD            _IOWR('n', 0, struct nvme_pt_command)
   42 #define NVME_RESET_CONTROLLER           _IO('n', 1)
   43 #define NVME_GET_NSID                   _IOR('n', 2, struct nvme_get_nsid)
   44 #define NVME_GET_MAX_XFER_SIZE          _IOR('n', 3, uint64_t)
   45 
   46 #define NVME_IO_TEST                    _IOWR('n', 100, struct nvme_io_test)
   47 #define NVME_BIO_TEST                   _IOWR('n', 101, struct nvme_io_test)
   48 
   49 /*
   50  * Macros to deal with NVME revisions, as defined VS register
   51  */
   52 #define NVME_REV(x, y)                  (((x) << 16) | ((y) << 8))
   53 #define NVME_MAJOR(r)                   (((r) >> 16) & 0xffff)
   54 #define NVME_MINOR(r)                   (((r) >> 8) & 0xff)
   55 
   56 /*
   57  * Use to mark a command to apply to all namespaces, or to retrieve global
   58  *  log pages.
   59  */
   60 #define NVME_GLOBAL_NAMESPACE_TAG       ((uint32_t)0xFFFFFFFF)
   61 
   62 /* Cap transfers by the maximum addressable by page-sized PRP (4KB -> 2MB). */
   63 #define NVME_MAX_XFER_SIZE              MIN(maxphys, (PAGE_SIZE/8*PAGE_SIZE))
   64 
   65 /* Register field definitions */
   66 #define NVME_CAP_LO_REG_MQES_SHIFT                      (0)
   67 #define NVME_CAP_LO_REG_MQES_MASK                       (0xFFFF)
   68 #define NVME_CAP_LO_REG_CQR_SHIFT                       (16)
   69 #define NVME_CAP_LO_REG_CQR_MASK                        (0x1)
   70 #define NVME_CAP_LO_REG_AMS_SHIFT                       (17)
   71 #define NVME_CAP_LO_REG_AMS_MASK                        (0x3)
   72 #define NVME_CAP_LO_REG_TO_SHIFT                        (24)
   73 #define NVME_CAP_LO_REG_TO_MASK                         (0xFF)
   74 #define NVME_CAP_LO_MQES(x) \
   75         (((x) >> NVME_CAP_LO_REG_MQES_SHIFT) & NVME_CAP_LO_REG_MQES_MASK)
   76 #define NVME_CAP_LO_CQR(x) \
   77         (((x) >> NVME_CAP_LO_REG_CQR_SHIFT) & NVME_CAP_LO_REG_CQR_MASK)
   78 #define NVME_CAP_LO_AMS(x) \
   79         (((x) >> NVME_CAP_LO_REG_AMS_SHIFT) & NVME_CAP_LO_REG_AMS_MASK)
   80 #define NVME_CAP_LO_TO(x) \
   81         (((x) >> NVME_CAP_LO_REG_TO_SHIFT) & NVME_CAP_LO_REG_TO_MASK)
   82 
   83 #define NVME_CAP_HI_REG_DSTRD_SHIFT                     (0)
   84 #define NVME_CAP_HI_REG_DSTRD_MASK                      (0xF)
   85 #define NVME_CAP_HI_REG_NSSRS_SHIFT                     (4)
   86 #define NVME_CAP_HI_REG_NSSRS_MASK                      (0x1)
   87 #define NVME_CAP_HI_REG_CSS_SHIFT                       (5)
   88 #define NVME_CAP_HI_REG_CSS_MASK                        (0xff)
   89 #define NVME_CAP_HI_REG_CSS_NVM_SHIFT                   (5)
   90 #define NVME_CAP_HI_REG_CSS_NVM_MASK                    (0x1)
   91 #define NVME_CAP_HI_REG_BPS_SHIFT                       (13)
   92 #define NVME_CAP_HI_REG_BPS_MASK                        (0x1)
   93 #define NVME_CAP_HI_REG_MPSMIN_SHIFT                    (16)
   94 #define NVME_CAP_HI_REG_MPSMIN_MASK                     (0xF)
   95 #define NVME_CAP_HI_REG_MPSMAX_SHIFT                    (20)
   96 #define NVME_CAP_HI_REG_MPSMAX_MASK                     (0xF)
   97 #define NVME_CAP_HI_REG_PMRS_SHIFT                      (24)
   98 #define NVME_CAP_HI_REG_PMRS_MASK                       (0x1)
   99 #define NVME_CAP_HI_REG_CMBS_SHIFT                      (25)
  100 #define NVME_CAP_HI_REG_CMBS_MASK                       (0x1)
  101 #define NVME_CAP_HI_DSTRD(x) \
  102         (((x) >> NVME_CAP_HI_REG_DSTRD_SHIFT) & NVME_CAP_HI_REG_DSTRD_MASK)
  103 #define NVME_CAP_HI_NSSRS(x) \
  104         (((x) >> NVME_CAP_HI_REG_NSSRS_SHIFT) & NVME_CAP_HI_REG_NSSRS_MASK)
  105 #define NVME_CAP_HI_CSS(x) \
  106         (((x) >> NVME_CAP_HI_REG_CSS_SHIFT) & NVME_CAP_HI_REG_CSS_MASK)
  107 #define NVME_CAP_HI_CSS_NVM(x) \
  108         (((x) >> NVME_CAP_HI_REG_CSS_NVM_SHIFT) & NVME_CAP_HI_REG_CSS_NVM_MASK)
  109 #define NVME_CAP_HI_BPS(x) \
  110         (((x) >> NVME_CAP_HI_REG_BPS_SHIFT) & NVME_CAP_HI_REG_BPS_MASK)
  111 #define NVME_CAP_HI_MPSMIN(x) \
  112         (((x) >> NVME_CAP_HI_REG_MPSMIN_SHIFT) & NVME_CAP_HI_REG_MPSMIN_MASK)
  113 #define NVME_CAP_HI_MPSMAX(x) \
  114         (((x) >> NVME_CAP_HI_REG_MPSMAX_SHIFT) & NVME_CAP_HI_REG_MPSMAX_MASK)
  115 #define NVME_CAP_HI_PMRS(x) \
  116         (((x) >> NVME_CAP_HI_REG_PMRS_SHIFT) & NVME_CAP_HI_REG_PMRS_MASK)
  117 #define NVME_CAP_HI_CMBS(x) \
  118         (((x) >> NVME_CAP_HI_REG_CMBS_SHIFT) & NVME_CAP_HI_REG_CMBS_MASK)
  119 
  120 #define NVME_CC_REG_EN_SHIFT                            (0)
  121 #define NVME_CC_REG_EN_MASK                             (0x1)
  122 #define NVME_CC_REG_CSS_SHIFT                           (4)
  123 #define NVME_CC_REG_CSS_MASK                            (0x7)
  124 #define NVME_CC_REG_MPS_SHIFT                           (7)
  125 #define NVME_CC_REG_MPS_MASK                            (0xF)
  126 #define NVME_CC_REG_AMS_SHIFT                           (11)
  127 #define NVME_CC_REG_AMS_MASK                            (0x7)
  128 #define NVME_CC_REG_SHN_SHIFT                           (14)
  129 #define NVME_CC_REG_SHN_MASK                            (0x3)
  130 #define NVME_CC_REG_IOSQES_SHIFT                        (16)
  131 #define NVME_CC_REG_IOSQES_MASK                         (0xF)
  132 #define NVME_CC_REG_IOCQES_SHIFT                        (20)
  133 #define NVME_CC_REG_IOCQES_MASK                         (0xF)
  134 
  135 #define NVME_CSTS_REG_RDY_SHIFT                         (0)
  136 #define NVME_CSTS_REG_RDY_MASK                          (0x1)
  137 #define NVME_CSTS_REG_CFS_SHIFT                         (1)
  138 #define NVME_CSTS_REG_CFS_MASK                          (0x1)
  139 #define NVME_CSTS_REG_SHST_SHIFT                        (2)
  140 #define NVME_CSTS_REG_SHST_MASK                         (0x3)
  141 #define NVME_CSTS_REG_NVSRO_SHIFT                       (4)
  142 #define NVME_CSTS_REG_NVSRO_MASK                        (0x1)
  143 #define NVME_CSTS_REG_PP_SHIFT                          (5)
  144 #define NVME_CSTS_REG_PP_MASK                           (0x1)
  145 
  146 #define NVME_CSTS_GET_SHST(csts)                        (((csts) >> NVME_CSTS_REG_SHST_SHIFT) & NVME_CSTS_REG_SHST_MASK)
  147 
  148 #define NVME_AQA_REG_ASQS_SHIFT                         (0)
  149 #define NVME_AQA_REG_ASQS_MASK                          (0xFFF)
  150 #define NVME_AQA_REG_ACQS_SHIFT                         (16)
  151 #define NVME_AQA_REG_ACQS_MASK                          (0xFFF)
  152 
  153 #define NVME_PMRCAP_REG_RDS_SHIFT                       (3)
  154 #define NVME_PMRCAP_REG_RDS_MASK                        (0x1)
  155 #define NVME_PMRCAP_REG_WDS_SHIFT                       (4)
  156 #define NVME_PMRCAP_REG_WDS_MASK                        (0x1)
  157 #define NVME_PMRCAP_REG_BIR_SHIFT                       (5)
  158 #define NVME_PMRCAP_REG_BIR_MASK                        (0x7)
  159 #define NVME_PMRCAP_REG_PMRTU_SHIFT                     (8)
  160 #define NVME_PMRCAP_REG_PMRTU_MASK                      (0x3)
  161 #define NVME_PMRCAP_REG_PMRWBM_SHIFT                    (10)
  162 #define NVME_PMRCAP_REG_PMRWBM_MASK                     (0xf)
  163 #define NVME_PMRCAP_REG_PMRTO_SHIFT                     (16)
  164 #define NVME_PMRCAP_REG_PMRTO_MASK                      (0xff)
  165 #define NVME_PMRCAP_REG_CMSS_SHIFT                      (24)
  166 #define NVME_PMRCAP_REG_CMSS_MASK                       (0x1)
  167 
  168 #define NVME_PMRCAP_RDS(x) \
  169         (((x) >> NVME_PMRCAP_REG_RDS_SHIFT) & NVME_PMRCAP_REG_RDS_MASK)
  170 #define NVME_PMRCAP_WDS(x) \
  171         (((x) >> NVME_PMRCAP_REG_WDS_SHIFT) & NVME_PMRCAP_REG_WDS_MASK)
  172 #define NVME_PMRCAP_BIR(x) \
  173         (((x) >> NVME_PMRCAP_REG_BIR_SHIFT) & NVME_PMRCAP_REG_BIR_MASK)
  174 #define NVME_PMRCAP_PMRTU(x) \
  175         (((x) >> NVME_PMRCAP_REG_PMRTU_SHIFT) & NVME_PMRCAP_REG_PMRTU_MASK)
  176 #define NVME_PMRCAP_PMRWBM(x) \
  177         (((x) >> NVME_PMRCAP_REG_PMRWBM_SHIFT) & NVME_PMRCAP_REG_PMRWBM_MASK)
  178 #define NVME_PMRCAP_PMRTO(x) \
  179         (((x) >> NVME_PMRCAP_REG_PMRTO_SHIFT) & NVME_PMRCAP_REG_PMRTO_MASK)
  180 #define NVME_PMRCAP_CMSS(x) \
  181         (((x) >> NVME_PMRCAP_REG_CMSS_SHIFT) & NVME_PMRCAP_REG_CMSS_MASK)
  182 
  183 /* Command field definitions */
  184 
  185 #define NVME_CMD_FUSE_SHIFT                             (8)
  186 #define NVME_CMD_FUSE_MASK                              (0x3)
  187 
  188 #define NVME_STATUS_P_SHIFT                             (0)
  189 #define NVME_STATUS_P_MASK                              (0x1)
  190 #define NVME_STATUS_SC_SHIFT                            (1)
  191 #define NVME_STATUS_SC_MASK                             (0xFF)
  192 #define NVME_STATUS_SCT_SHIFT                           (9)
  193 #define NVME_STATUS_SCT_MASK                            (0x7)
  194 #define NVME_STATUS_CRD_SHIFT                           (12)
  195 #define NVME_STATUS_CRD_MASK                            (0x3)
  196 #define NVME_STATUS_M_SHIFT                             (14)
  197 #define NVME_STATUS_M_MASK                              (0x1)
  198 #define NVME_STATUS_DNR_SHIFT                           (15)
  199 #define NVME_STATUS_DNR_MASK                            (0x1)
  200 
  201 #define NVME_STATUS_GET_P(st)                           (((st) >> NVME_STATUS_P_SHIFT) & NVME_STATUS_P_MASK)
  202 #define NVME_STATUS_GET_SC(st)                          (((st) >> NVME_STATUS_SC_SHIFT) & NVME_STATUS_SC_MASK)
  203 #define NVME_STATUS_GET_SCT(st)                         (((st) >> NVME_STATUS_SCT_SHIFT) & NVME_STATUS_SCT_MASK)
  204 #define NVME_STATUS_GET_M(st)                           (((st) >> NVME_STATUS_M_SHIFT) & NVME_STATUS_M_MASK)
  205 #define NVME_STATUS_GET_DNR(st)                         (((st) >> NVME_STATUS_DNR_SHIFT) & NVME_STATUS_DNR_MASK)
  206 
  207 #define NVME_PWR_ST_MPS_SHIFT                           (0)
  208 #define NVME_PWR_ST_MPS_MASK                            (0x1)
  209 #define NVME_PWR_ST_NOPS_SHIFT                          (1)
  210 #define NVME_PWR_ST_NOPS_MASK                           (0x1)
  211 #define NVME_PWR_ST_RRT_SHIFT                           (0)
  212 #define NVME_PWR_ST_RRT_MASK                            (0x1F)
  213 #define NVME_PWR_ST_RRL_SHIFT                           (0)
  214 #define NVME_PWR_ST_RRL_MASK                            (0x1F)
  215 #define NVME_PWR_ST_RWT_SHIFT                           (0)
  216 #define NVME_PWR_ST_RWT_MASK                            (0x1F)
  217 #define NVME_PWR_ST_RWL_SHIFT                           (0)
  218 #define NVME_PWR_ST_RWL_MASK                            (0x1F)
  219 #define NVME_PWR_ST_IPS_SHIFT                           (6)
  220 #define NVME_PWR_ST_IPS_MASK                            (0x3)
  221 #define NVME_PWR_ST_APW_SHIFT                           (0)
  222 #define NVME_PWR_ST_APW_MASK                            (0x7)
  223 #define NVME_PWR_ST_APS_SHIFT                           (6)
  224 #define NVME_PWR_ST_APS_MASK                            (0x3)
  225 
  226 /** Controller Multi-path I/O and Namespace Sharing Capabilities */
  227 /* More then one port */
  228 #define NVME_CTRLR_DATA_MIC_MPORTS_SHIFT                (0)
  229 #define NVME_CTRLR_DATA_MIC_MPORTS_MASK                 (0x1)
  230 /* More then one controller */
  231 #define NVME_CTRLR_DATA_MIC_MCTRLRS_SHIFT               (1)
  232 #define NVME_CTRLR_DATA_MIC_MCTRLRS_MASK                (0x1)
  233 /* SR-IOV Virtual Function */
  234 #define NVME_CTRLR_DATA_MIC_SRIOVVF_SHIFT               (2)
  235 #define NVME_CTRLR_DATA_MIC_SRIOVVF_MASK                (0x1)
  236 /* Asymmetric Namespace Access Reporting */
  237 #define NVME_CTRLR_DATA_MIC_ANAR_SHIFT                  (3)
  238 #define NVME_CTRLR_DATA_MIC_ANAR_MASK                   (0x1)
  239 
  240 /** OACS - optional admin command support */
  241 /* supports security send/receive commands */
  242 #define NVME_CTRLR_DATA_OACS_SECURITY_SHIFT             (0)
  243 #define NVME_CTRLR_DATA_OACS_SECURITY_MASK              (0x1)
  244 /* supports format nvm command */
  245 #define NVME_CTRLR_DATA_OACS_FORMAT_SHIFT               (1)
  246 #define NVME_CTRLR_DATA_OACS_FORMAT_MASK                (0x1)
  247 /* supports firmware activate/download commands */
  248 #define NVME_CTRLR_DATA_OACS_FIRMWARE_SHIFT             (2)
  249 #define NVME_CTRLR_DATA_OACS_FIRMWARE_MASK              (0x1)
  250 /* supports namespace management commands */
  251 #define NVME_CTRLR_DATA_OACS_NSMGMT_SHIFT               (3)
  252 #define NVME_CTRLR_DATA_OACS_NSMGMT_MASK                (0x1)
  253 /* supports Device Self-test command */
  254 #define NVME_CTRLR_DATA_OACS_SELFTEST_SHIFT             (4)
  255 #define NVME_CTRLR_DATA_OACS_SELFTEST_MASK              (0x1)
  256 /* supports Directives */
  257 #define NVME_CTRLR_DATA_OACS_DIRECTIVES_SHIFT           (5)
  258 #define NVME_CTRLR_DATA_OACS_DIRECTIVES_MASK            (0x1)
  259 /* supports NVMe-MI Send/Receive */
  260 #define NVME_CTRLR_DATA_OACS_NVMEMI_SHIFT               (6)
  261 #define NVME_CTRLR_DATA_OACS_NVMEMI_MASK                (0x1)
  262 /* supports Virtualization Management */
  263 #define NVME_CTRLR_DATA_OACS_VM_SHIFT                   (7)
  264 #define NVME_CTRLR_DATA_OACS_VM_MASK                    (0x1)
  265 /* supports Doorbell Buffer Config */
  266 #define NVME_CTRLR_DATA_OACS_DBBUFFER_SHIFT             (8)
  267 #define NVME_CTRLR_DATA_OACS_DBBUFFER_MASK              (0x1)
  268 /* supports Get LBA Status */
  269 #define NVME_CTRLR_DATA_OACS_GETLBA_SHIFT               (9)
  270 #define NVME_CTRLR_DATA_OACS_GETLBA_MASK                (0x1)
  271 
  272 /** firmware updates */
  273 /* first slot is read-only */
  274 #define NVME_CTRLR_DATA_FRMW_SLOT1_RO_SHIFT             (0)
  275 #define NVME_CTRLR_DATA_FRMW_SLOT1_RO_MASK              (0x1)
  276 /* number of firmware slots */
  277 #define NVME_CTRLR_DATA_FRMW_NUM_SLOTS_SHIFT            (1)
  278 #define NVME_CTRLR_DATA_FRMW_NUM_SLOTS_MASK             (0x7)
  279 /* firmware activation without reset */
  280 #define NVME_CTRLR_DATA_FRMW_ACT_WO_RESET_SHIFT         (4)
  281 #define NVME_CTRLR_DATA_FRMW_ACT_WO_RESET_MASK          (0x1)
  282 
  283 /** log page attributes */
  284 /* per namespace smart/health log page */
  285 #define NVME_CTRLR_DATA_LPA_NS_SMART_SHIFT              (0)
  286 #define NVME_CTRLR_DATA_LPA_NS_SMART_MASK               (0x1)
  287 
  288 /** AVSCC - admin vendor specific command configuration */
  289 /* admin vendor specific commands use spec format */
  290 #define NVME_CTRLR_DATA_AVSCC_SPEC_FORMAT_SHIFT         (0)
  291 #define NVME_CTRLR_DATA_AVSCC_SPEC_FORMAT_MASK          (0x1)
  292 
  293 /** Autonomous Power State Transition Attributes */
  294 /* Autonomous Power State Transitions supported */
  295 #define NVME_CTRLR_DATA_APSTA_APST_SUPP_SHIFT           (0)
  296 #define NVME_CTRLR_DATA_APSTA_APST_SUPP_MASK            (0x1)
  297 
  298 /** Sanitize Capabilities */
  299 /* Crypto Erase Support  */
  300 #define NVME_CTRLR_DATA_SANICAP_CES_SHIFT               (0)
  301 #define NVME_CTRLR_DATA_SANICAP_CES_MASK                (0x1)
  302 /* Block Erase Support */
  303 #define NVME_CTRLR_DATA_SANICAP_BES_SHIFT               (1)
  304 #define NVME_CTRLR_DATA_SANICAP_BES_MASK                (0x1)
  305 /* Overwrite Support */
  306 #define NVME_CTRLR_DATA_SANICAP_OWS_SHIFT               (2)
  307 #define NVME_CTRLR_DATA_SANICAP_OWS_MASK                (0x1)
  308 /* No-Deallocate Inhibited  */
  309 #define NVME_CTRLR_DATA_SANICAP_NDI_SHIFT               (29)
  310 #define NVME_CTRLR_DATA_SANICAP_NDI_MASK                (0x1)
  311 /* No-Deallocate Modifies Media After Sanitize */
  312 #define NVME_CTRLR_DATA_SANICAP_NODMMAS_SHIFT           (30)
  313 #define NVME_CTRLR_DATA_SANICAP_NODMMAS_MASK            (0x3)
  314 #define NVME_CTRLR_DATA_SANICAP_NODMMAS_UNDEF           (0)
  315 #define NVME_CTRLR_DATA_SANICAP_NODMMAS_NO              (1)
  316 #define NVME_CTRLR_DATA_SANICAP_NODMMAS_YES             (2)
  317 
  318 /** submission queue entry size */
  319 #define NVME_CTRLR_DATA_SQES_MIN_SHIFT                  (0)
  320 #define NVME_CTRLR_DATA_SQES_MIN_MASK                   (0xF)
  321 #define NVME_CTRLR_DATA_SQES_MAX_SHIFT                  (4)
  322 #define NVME_CTRLR_DATA_SQES_MAX_MASK                   (0xF)
  323 
  324 /** completion queue entry size */
  325 #define NVME_CTRLR_DATA_CQES_MIN_SHIFT                  (0)
  326 #define NVME_CTRLR_DATA_CQES_MIN_MASK                   (0xF)
  327 #define NVME_CTRLR_DATA_CQES_MAX_SHIFT                  (4)
  328 #define NVME_CTRLR_DATA_CQES_MAX_MASK                   (0xF)
  329 
  330 /** optional nvm command support */
  331 #define NVME_CTRLR_DATA_ONCS_COMPARE_SHIFT              (0)
  332 #define NVME_CTRLR_DATA_ONCS_COMPARE_MASK               (0x1)
  333 #define NVME_CTRLR_DATA_ONCS_WRITE_UNC_SHIFT            (1)
  334 #define NVME_CTRLR_DATA_ONCS_WRITE_UNC_MASK             (0x1)
  335 #define NVME_CTRLR_DATA_ONCS_DSM_SHIFT                  (2)
  336 #define NVME_CTRLR_DATA_ONCS_DSM_MASK                   (0x1)
  337 #define NVME_CTRLR_DATA_ONCS_WRZERO_SHIFT               (3)
  338 #define NVME_CTRLR_DATA_ONCS_WRZERO_MASK                (0x1)
  339 #define NVME_CTRLR_DATA_ONCS_SAVEFEAT_SHIFT             (4)
  340 #define NVME_CTRLR_DATA_ONCS_SAVEFEAT_MASK              (0x1)
  341 #define NVME_CTRLR_DATA_ONCS_RESERV_SHIFT               (5)
  342 #define NVME_CTRLR_DATA_ONCS_RESERV_MASK                (0x1)
  343 #define NVME_CTRLR_DATA_ONCS_TIMESTAMP_SHIFT            (6)
  344 #define NVME_CTRLR_DATA_ONCS_TIMESTAMP_MASK             (0x1)
  345 #define NVME_CTRLR_DATA_ONCS_VERIFY_SHIFT               (7)
  346 #define NVME_CTRLR_DATA_ONCS_VERIFY_MASK                (0x1)
  347 
  348 /** Fused Operation Support */
  349 #define NVME_CTRLR_DATA_FUSES_CNW_SHIFT         (0)
  350 #define NVME_CTRLR_DATA_FUSES_CNW_MASK          (0x1)
  351 
  352 /** Format NVM Attributes */
  353 #define NVME_CTRLR_DATA_FNA_FORMAT_ALL_SHIFT            (0)
  354 #define NVME_CTRLR_DATA_FNA_FORMAT_ALL_MASK             (0x1)
  355 #define NVME_CTRLR_DATA_FNA_ERASE_ALL_SHIFT             (1)
  356 #define NVME_CTRLR_DATA_FNA_ERASE_ALL_MASK              (0x1)
  357 #define NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_SHIFT          (2)
  358 #define NVME_CTRLR_DATA_FNA_CRYPTO_ERASE_MASK           (0x1)
  359 
  360 /** volatile write cache */
  361 /* volatile write cache present */
  362 #define NVME_CTRLR_DATA_VWC_PRESENT_SHIFT               (0)
  363 #define NVME_CTRLR_DATA_VWC_PRESENT_MASK                (0x1)
  364 /* flush all namespaces supported */
  365 #define NVME_CTRLR_DATA_VWC_ALL_SHIFT                   (1)
  366 #define NVME_CTRLR_DATA_VWC_ALL_MASK                    (0x3)
  367 #define NVME_CTRLR_DATA_VWC_ALL_UNKNOWN                 (0)
  368 #define NVME_CTRLR_DATA_VWC_ALL_NO                      (2)
  369 #define NVME_CTRLR_DATA_VWC_ALL_YES                     (3)
  370 
  371 /** namespace features */
  372 /* thin provisioning */
  373 #define NVME_NS_DATA_NSFEAT_THIN_PROV_SHIFT             (0)
  374 #define NVME_NS_DATA_NSFEAT_THIN_PROV_MASK              (0x1)
  375 /* NAWUN, NAWUPF, and NACWU fields are valid */
  376 #define NVME_NS_DATA_NSFEAT_NA_FIELDS_SHIFT             (1)
  377 #define NVME_NS_DATA_NSFEAT_NA_FIELDS_MASK              (0x1)
  378 /* Deallocated or Unwritten Logical Block errors supported */
  379 #define NVME_NS_DATA_NSFEAT_DEALLOC_SHIFT               (2)
  380 #define NVME_NS_DATA_NSFEAT_DEALLOC_MASK                (0x1)
  381 /* NGUID and EUI64 fields are not reusable */
  382 #define NVME_NS_DATA_NSFEAT_NO_ID_REUSE_SHIFT           (3)
  383 #define NVME_NS_DATA_NSFEAT_NO_ID_REUSE_MASK            (0x1)
  384 /* NPWG, NPWA, NPDG, NPDA, and NOWS are valid */
  385 #define NVME_NS_DATA_NSFEAT_NPVALID_SHIFT               (4)
  386 #define NVME_NS_DATA_NSFEAT_NPVALID_MASK                (0x1)
  387 
  388 /** formatted lba size */
  389 #define NVME_NS_DATA_FLBAS_FORMAT_SHIFT                 (0)
  390 #define NVME_NS_DATA_FLBAS_FORMAT_MASK                  (0xF)
  391 #define NVME_NS_DATA_FLBAS_EXTENDED_SHIFT               (4)
  392 #define NVME_NS_DATA_FLBAS_EXTENDED_MASK                (0x1)
  393 
  394 /** metadata capabilities */
  395 /* metadata can be transferred as part of data prp list */
  396 #define NVME_NS_DATA_MC_EXTENDED_SHIFT                  (0)
  397 #define NVME_NS_DATA_MC_EXTENDED_MASK                   (0x1)
  398 /* metadata can be transferred with separate metadata pointer */
  399 #define NVME_NS_DATA_MC_POINTER_SHIFT                   (1)
  400 #define NVME_NS_DATA_MC_POINTER_MASK                    (0x1)
  401 
  402 /** end-to-end data protection capabilities */
  403 /* protection information type 1 */
  404 #define NVME_NS_DATA_DPC_PIT1_SHIFT                     (0)
  405 #define NVME_NS_DATA_DPC_PIT1_MASK                      (0x1)
  406 /* protection information type 2 */
  407 #define NVME_NS_DATA_DPC_PIT2_SHIFT                     (1)
  408 #define NVME_NS_DATA_DPC_PIT2_MASK                      (0x1)
  409 /* protection information type 3 */
  410 #define NVME_NS_DATA_DPC_PIT3_SHIFT                     (2)
  411 #define NVME_NS_DATA_DPC_PIT3_MASK                      (0x1)
  412 /* first eight bytes of metadata */
  413 #define NVME_NS_DATA_DPC_MD_START_SHIFT                 (3)
  414 #define NVME_NS_DATA_DPC_MD_START_MASK                  (0x1)
  415 /* last eight bytes of metadata */
  416 #define NVME_NS_DATA_DPC_MD_END_SHIFT                   (4)
  417 #define NVME_NS_DATA_DPC_MD_END_MASK                    (0x1)
  418 
  419 /** end-to-end data protection type settings */
  420 /* protection information type */
  421 #define NVME_NS_DATA_DPS_PIT_SHIFT                      (0)
  422 #define NVME_NS_DATA_DPS_PIT_MASK                       (0x7)
  423 /* 1 == protection info transferred at start of metadata */
  424 /* 0 == protection info transferred at end of metadata */
  425 #define NVME_NS_DATA_DPS_MD_START_SHIFT                 (3)
  426 #define NVME_NS_DATA_DPS_MD_START_MASK                  (0x1)
  427 
  428 /** Namespace Multi-path I/O and Namespace Sharing Capabilities */
  429 /* the namespace may be attached to two or more controllers */
  430 #define NVME_NS_DATA_NMIC_MAY_BE_SHARED_SHIFT           (0)
  431 #define NVME_NS_DATA_NMIC_MAY_BE_SHARED_MASK            (0x1)
  432 
  433 /** Reservation Capabilities */
  434 /* Persist Through Power Loss */
  435 #define NVME_NS_DATA_RESCAP_PTPL_SHIFT          (0)
  436 #define NVME_NS_DATA_RESCAP_PTPL_MASK           (0x1)
  437 /* supports the Write Exclusive */
  438 #define NVME_NS_DATA_RESCAP_WR_EX_SHIFT         (1)
  439 #define NVME_NS_DATA_RESCAP_WR_EX_MASK          (0x1)
  440 /* supports the Exclusive Access */
  441 #define NVME_NS_DATA_RESCAP_EX_AC_SHIFT         (2)
  442 #define NVME_NS_DATA_RESCAP_EX_AC_MASK          (0x1)
  443 /* supports the Write Exclusive – Registrants Only */
  444 #define NVME_NS_DATA_RESCAP_WR_EX_RO_SHIFT      (3)
  445 #define NVME_NS_DATA_RESCAP_WR_EX_RO_MASK       (0x1)
  446 /* supports the Exclusive Access - Registrants Only */
  447 #define NVME_NS_DATA_RESCAP_EX_AC_RO_SHIFT      (4)
  448 #define NVME_NS_DATA_RESCAP_EX_AC_RO_MASK       (0x1)
  449 /* supports the Write Exclusive – All Registrants */
  450 #define NVME_NS_DATA_RESCAP_WR_EX_AR_SHIFT      (5)
  451 #define NVME_NS_DATA_RESCAP_WR_EX_AR_MASK       (0x1)
  452 /* supports the Exclusive Access - All Registrants */
  453 #define NVME_NS_DATA_RESCAP_EX_AC_AR_SHIFT      (6)
  454 #define NVME_NS_DATA_RESCAP_EX_AC_AR_MASK       (0x1)
  455 /* Ignore Existing Key is used as defined in revision 1.3 or later */
  456 #define NVME_NS_DATA_RESCAP_IEKEY13_SHIFT       (7)
  457 #define NVME_NS_DATA_RESCAP_IEKEY13_MASK        (0x1)
  458 
  459 /** Format Progress Indicator */
  460 /* percentage of the Format NVM command that remains to be completed */
  461 #define NVME_NS_DATA_FPI_PERC_SHIFT             (0)
  462 #define NVME_NS_DATA_FPI_PERC_MASK              (0x7f)
  463 /* namespace supports the Format Progress Indicator */
  464 #define NVME_NS_DATA_FPI_SUPP_SHIFT             (7)
  465 #define NVME_NS_DATA_FPI_SUPP_MASK              (0x1)
  466 
  467 /** Deallocate Logical Block Features */
  468 /* deallocated logical block read behavior */
  469 #define NVME_NS_DATA_DLFEAT_READ_SHIFT          (0)
  470 #define NVME_NS_DATA_DLFEAT_READ_MASK           (0x07)
  471 #define NVME_NS_DATA_DLFEAT_READ_NR             (0x00)
  472 #define NVME_NS_DATA_DLFEAT_READ_00             (0x01)
  473 #define NVME_NS_DATA_DLFEAT_READ_FF             (0x02)
  474 /* supports the Deallocate bit in the Write Zeroes */
  475 #define NVME_NS_DATA_DLFEAT_DWZ_SHIFT           (3)
  476 #define NVME_NS_DATA_DLFEAT_DWZ_MASK            (0x01)
  477 /* Guard field for deallocated logical blocks is set to the CRC  */
  478 #define NVME_NS_DATA_DLFEAT_GCRC_SHIFT          (4)
  479 #define NVME_NS_DATA_DLFEAT_GCRC_MASK           (0x01)
  480 
  481 /** lba format support */
  482 /* metadata size */
  483 #define NVME_NS_DATA_LBAF_MS_SHIFT                      (0)
  484 #define NVME_NS_DATA_LBAF_MS_MASK                       (0xFFFF)
  485 /* lba data size */
  486 #define NVME_NS_DATA_LBAF_LBADS_SHIFT                   (16)
  487 #define NVME_NS_DATA_LBAF_LBADS_MASK                    (0xFF)
  488 /* relative performance */
  489 #define NVME_NS_DATA_LBAF_RP_SHIFT                      (24)
  490 #define NVME_NS_DATA_LBAF_RP_MASK                       (0x3)
  491 
  492 enum nvme_critical_warning_state {
  493         NVME_CRIT_WARN_ST_AVAILABLE_SPARE               = 0x1,
  494         NVME_CRIT_WARN_ST_TEMPERATURE                   = 0x2,
  495         NVME_CRIT_WARN_ST_DEVICE_RELIABILITY            = 0x4,
  496         NVME_CRIT_WARN_ST_READ_ONLY                     = 0x8,
  497         NVME_CRIT_WARN_ST_VOLATILE_MEMORY_BACKUP        = 0x10,
  498 };
  499 #define NVME_CRIT_WARN_ST_RESERVED_MASK                 (0xE0)
  500 #define NVME_ASYNC_EVENT_NS_ATTRIBUTE                   (0x100)
  501 #define NVME_ASYNC_EVENT_FW_ACTIVATE                    (0x200)
  502 
  503 /* slot for current FW */
  504 #define NVME_FIRMWARE_PAGE_AFI_SLOT_SHIFT               (0)
  505 #define NVME_FIRMWARE_PAGE_AFI_SLOT_MASK                (0x7)
  506 
  507 /* Commands Supported and Effects */
  508 #define NVME_CE_PAGE_CSUP_SHIFT                         (0)
  509 #define NVME_CE_PAGE_CSUP_MASK                          (0x1)
  510 #define NVME_CE_PAGE_LBCC_SHIFT                         (1)
  511 #define NVME_CE_PAGE_LBCC_MASK                          (0x1)
  512 #define NVME_CE_PAGE_NCC_SHIFT                          (2)
  513 #define NVME_CE_PAGE_NCC_MASK                           (0x1)
  514 #define NVME_CE_PAGE_NIC_SHIFT                          (3)
  515 #define NVME_CE_PAGE_NIC_MASK                           (0x1)
  516 #define NVME_CE_PAGE_CCC_SHIFT                          (4)
  517 #define NVME_CE_PAGE_CCC_MASK                           (0x1)
  518 #define NVME_CE_PAGE_CSE_SHIFT                          (16)
  519 #define NVME_CE_PAGE_CSE_MASK                           (0x7)
  520 #define NVME_CE_PAGE_UUID_SHIFT                         (19)
  521 #define NVME_CE_PAGE_UUID_MASK                          (0x1)
  522 
  523 /* Sanitize Status */
  524 #define NVME_SS_PAGE_SSTAT_STATUS_SHIFT                 (0)
  525 #define NVME_SS_PAGE_SSTAT_STATUS_MASK                  (0x7)
  526 #define NVME_SS_PAGE_SSTAT_STATUS_NEVER                 (0)
  527 #define NVME_SS_PAGE_SSTAT_STATUS_COMPLETED             (1)
  528 #define NVME_SS_PAGE_SSTAT_STATUS_INPROG                (2)
  529 #define NVME_SS_PAGE_SSTAT_STATUS_FAILED                (3)
  530 #define NVME_SS_PAGE_SSTAT_STATUS_COMPLETEDWD           (4)
  531 #define NVME_SS_PAGE_SSTAT_PASSES_SHIFT                 (3)
  532 #define NVME_SS_PAGE_SSTAT_PASSES_MASK                  (0x1f)
  533 #define NVME_SS_PAGE_SSTAT_GDE_SHIFT                    (8)
  534 #define NVME_SS_PAGE_SSTAT_GDE_MASK                     (0x1)
  535 
  536 /* CC register SHN field values */
  537 enum shn_value {
  538         NVME_SHN_NORMAL         = 0x1,
  539         NVME_SHN_ABRUPT         = 0x2,
  540 };
  541 
  542 /* CSTS register SHST field values */
  543 enum shst_value {
  544         NVME_SHST_NORMAL        = 0x0,
  545         NVME_SHST_OCCURRING     = 0x1,
  546         NVME_SHST_COMPLETE      = 0x2,
  547 };
  548 
  549 struct nvme_registers {
  550         uint32_t        cap_lo; /* controller capabilities */
  551         uint32_t        cap_hi;
  552         uint32_t        vs;     /* version */
  553         uint32_t        intms;  /* interrupt mask set */
  554         uint32_t        intmc;  /* interrupt mask clear */
  555         uint32_t        cc;     /* controller configuration */
  556         uint32_t        reserved1;
  557         uint32_t        csts;   /* controller status */
  558         uint32_t        nssr;   /* NVM Subsystem Reset */
  559         uint32_t        aqa;    /* admin queue attributes */
  560         uint64_t        asq;    /* admin submission queue base addr */
  561         uint64_t        acq;    /* admin completion queue base addr */
  562         uint32_t        cmbloc; /* Controller Memory Buffer Location */
  563         uint32_t        cmbsz;  /* Controller Memory Buffer Size */
  564         uint32_t        bpinfo; /* Boot Partition Information */
  565         uint32_t        bprsel; /* Boot Partition Read Select */
  566         uint64_t        bpmbl;  /* Boot Partition Memory Buffer Location */
  567         uint64_t        cmbmsc; /* Controller Memory Buffer Memory Space Control */
  568         uint32_t        cmbsts; /* Controller Memory Buffer Status */
  569         uint8_t         reserved3[3492]; /* 5Ch - DFFh */
  570         uint32_t        pmrcap; /* Persistent Memory Capabilities */
  571         uint32_t        pmrctl; /* Persistent Memory Region Control */
  572         uint32_t        pmrsts; /* Persistent Memory Region Status */
  573         uint32_t        pmrebs; /* Persistent Memory Region Elasticity Buffer Size */
  574         uint32_t        pmrswtp; /* Persistent Memory Region Sustained Write Throughput */
  575         uint32_t        pmrmsc_lo; /* Persistent Memory Region Controller Memory Space Control */
  576         uint32_t        pmrmsc_hi;
  577         uint8_t         reserved4[484]; /* E1Ch - FFFh */
  578         struct {
  579             uint32_t    sq_tdbl; /* submission queue tail doorbell */
  580             uint32_t    cq_hdbl; /* completion queue head doorbell */
  581         } doorbell[1];
  582 };
  583 
  584 _Static_assert(sizeof(struct nvme_registers) == 0x1008, "bad size for nvme_registers");
  585 
  586 struct nvme_command {
  587         /* dword 0 */
  588         uint8_t opc;            /* opcode */
  589         uint8_t fuse;           /* fused operation */
  590         uint16_t cid;           /* command identifier */
  591 
  592         /* dword 1 */
  593         uint32_t nsid;          /* namespace identifier */
  594 
  595         /* dword 2-3 */
  596         uint32_t rsvd2;
  597         uint32_t rsvd3;
  598 
  599         /* dword 4-5 */
  600         uint64_t mptr;          /* metadata pointer */
  601 
  602         /* dword 6-7 */
  603         uint64_t prp1;          /* prp entry 1 */
  604 
  605         /* dword 8-9 */
  606         uint64_t prp2;          /* prp entry 2 */
  607 
  608         /* dword 10-15 */
  609         uint32_t cdw10;         /* command-specific */
  610         uint32_t cdw11;         /* command-specific */
  611         uint32_t cdw12;         /* command-specific */
  612         uint32_t cdw13;         /* command-specific */
  613         uint32_t cdw14;         /* command-specific */
  614         uint32_t cdw15;         /* command-specific */
  615 };
  616 
  617 _Static_assert(sizeof(struct nvme_command) == 16 * 4, "bad size for nvme_command");
  618 
  619 struct nvme_completion {
  620         /* dword 0 */
  621         uint32_t                cdw0;   /* command-specific */
  622 
  623         /* dword 1 */
  624         uint32_t                rsvd1;
  625 
  626         /* dword 2 */
  627         uint16_t                sqhd;   /* submission queue head pointer */
  628         uint16_t                sqid;   /* submission queue identifier */
  629 
  630         /* dword 3 */
  631         uint16_t                cid;    /* command identifier */
  632         uint16_t                status;
  633 } __aligned(8); /* riscv: nvme_qpair_process_completions has better code gen */
  634 
  635 _Static_assert(sizeof(struct nvme_completion) == 4 * 4, "bad size for nvme_completion");
  636 
  637 struct nvme_dsm_range {
  638         uint32_t attributes;
  639         uint32_t length;
  640         uint64_t starting_lba;
  641 };
  642 
  643 /* Largest DSM Trim that can be done */
  644 #define NVME_MAX_DSM_TRIM               4096
  645 
  646 _Static_assert(sizeof(struct nvme_dsm_range) == 16, "bad size for nvme_dsm_ranage");
  647 
  648 /* status code types */
  649 enum nvme_status_code_type {
  650         NVME_SCT_GENERIC                = 0x0,
  651         NVME_SCT_COMMAND_SPECIFIC       = 0x1,
  652         NVME_SCT_MEDIA_ERROR            = 0x2,
  653         NVME_SCT_PATH_RELATED           = 0x3,
  654         /* 0x3-0x6 - reserved */
  655         NVME_SCT_VENDOR_SPECIFIC        = 0x7,
  656 };
  657 
  658 /* generic command status codes */
  659 enum nvme_generic_command_status_code {
  660         NVME_SC_SUCCESS                         = 0x00,
  661         NVME_SC_INVALID_OPCODE                  = 0x01,
  662         NVME_SC_INVALID_FIELD                   = 0x02,
  663         NVME_SC_COMMAND_ID_CONFLICT             = 0x03,
  664         NVME_SC_DATA_TRANSFER_ERROR             = 0x04,
  665         NVME_SC_ABORTED_POWER_LOSS              = 0x05,
  666         NVME_SC_INTERNAL_DEVICE_ERROR           = 0x06,
  667         NVME_SC_ABORTED_BY_REQUEST              = 0x07,
  668         NVME_SC_ABORTED_SQ_DELETION             = 0x08,
  669         NVME_SC_ABORTED_FAILED_FUSED            = 0x09,
  670         NVME_SC_ABORTED_MISSING_FUSED           = 0x0a,
  671         NVME_SC_INVALID_NAMESPACE_OR_FORMAT     = 0x0b,
  672         NVME_SC_COMMAND_SEQUENCE_ERROR          = 0x0c,
  673         NVME_SC_INVALID_SGL_SEGMENT_DESCR       = 0x0d,
  674         NVME_SC_INVALID_NUMBER_OF_SGL_DESCR     = 0x0e,
  675         NVME_SC_DATA_SGL_LENGTH_INVALID         = 0x0f,
  676         NVME_SC_METADATA_SGL_LENGTH_INVALID     = 0x10,
  677         NVME_SC_SGL_DESCRIPTOR_TYPE_INVALID     = 0x11,
  678         NVME_SC_INVALID_USE_OF_CMB              = 0x12,
  679         NVME_SC_PRP_OFFET_INVALID               = 0x13,
  680         NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED      = 0x14,
  681         NVME_SC_OPERATION_DENIED                = 0x15,
  682         NVME_SC_SGL_OFFSET_INVALID              = 0x16,
  683         /* 0x17 - reserved */
  684         NVME_SC_HOST_ID_INCONSISTENT_FORMAT     = 0x18,
  685         NVME_SC_KEEP_ALIVE_TIMEOUT_EXPIRED      = 0x19,
  686         NVME_SC_KEEP_ALIVE_TIMEOUT_INVALID      = 0x1a,
  687         NVME_SC_ABORTED_DUE_TO_PREEMPT          = 0x1b,
  688         NVME_SC_SANITIZE_FAILED                 = 0x1c,
  689         NVME_SC_SANITIZE_IN_PROGRESS            = 0x1d,
  690         NVME_SC_SGL_DATA_BLOCK_GRAN_INVALID     = 0x1e,
  691         NVME_SC_NOT_SUPPORTED_IN_CMB            = 0x1f,
  692         NVME_SC_NAMESPACE_IS_WRITE_PROTECTED    = 0x20,
  693         NVME_SC_COMMAND_INTERRUPTED             = 0x21,
  694         NVME_SC_TRANSIENT_TRANSPORT_ERROR       = 0x22,
  695 
  696         NVME_SC_LBA_OUT_OF_RANGE                = 0x80,
  697         NVME_SC_CAPACITY_EXCEEDED               = 0x81,
  698         NVME_SC_NAMESPACE_NOT_READY             = 0x82,
  699         NVME_SC_RESERVATION_CONFLICT            = 0x83,
  700         NVME_SC_FORMAT_IN_PROGRESS              = 0x84,
  701 };
  702 
  703 /* command specific status codes */
  704 enum nvme_command_specific_status_code {
  705         NVME_SC_COMPLETION_QUEUE_INVALID        = 0x00,
  706         NVME_SC_INVALID_QUEUE_IDENTIFIER        = 0x01,
  707         NVME_SC_MAXIMUM_QUEUE_SIZE_EXCEEDED     = 0x02,
  708         NVME_SC_ABORT_COMMAND_LIMIT_EXCEEDED    = 0x03,
  709         /* 0x04 - reserved */
  710         NVME_SC_ASYNC_EVENT_REQUEST_LIMIT_EXCEEDED = 0x05,
  711         NVME_SC_INVALID_FIRMWARE_SLOT           = 0x06,
  712         NVME_SC_INVALID_FIRMWARE_IMAGE          = 0x07,
  713         NVME_SC_INVALID_INTERRUPT_VECTOR        = 0x08,
  714         NVME_SC_INVALID_LOG_PAGE                = 0x09,
  715         NVME_SC_INVALID_FORMAT                  = 0x0a,
  716         NVME_SC_FIRMWARE_REQUIRES_RESET         = 0x0b,
  717         NVME_SC_INVALID_QUEUE_DELETION          = 0x0c,
  718         NVME_SC_FEATURE_NOT_SAVEABLE            = 0x0d,
  719         NVME_SC_FEATURE_NOT_CHANGEABLE          = 0x0e,
  720         NVME_SC_FEATURE_NOT_NS_SPECIFIC         = 0x0f,
  721         NVME_SC_FW_ACT_REQUIRES_NVMS_RESET      = 0x10,
  722         NVME_SC_FW_ACT_REQUIRES_RESET           = 0x11,
  723         NVME_SC_FW_ACT_REQUIRES_TIME            = 0x12,
  724         NVME_SC_FW_ACT_PROHIBITED               = 0x13,
  725         NVME_SC_OVERLAPPING_RANGE               = 0x14,
  726         NVME_SC_NS_INSUFFICIENT_CAPACITY        = 0x15,
  727         NVME_SC_NS_ID_UNAVAILABLE               = 0x16,
  728         /* 0x17 - reserved */
  729         NVME_SC_NS_ALREADY_ATTACHED             = 0x18,
  730         NVME_SC_NS_IS_PRIVATE                   = 0x19,
  731         NVME_SC_NS_NOT_ATTACHED                 = 0x1a,
  732         NVME_SC_THIN_PROV_NOT_SUPPORTED         = 0x1b,
  733         NVME_SC_CTRLR_LIST_INVALID              = 0x1c,
  734         NVME_SC_SELF_TEST_IN_PROGRESS           = 0x1d,
  735         NVME_SC_BOOT_PART_WRITE_PROHIB          = 0x1e,
  736         NVME_SC_INVALID_CTRLR_ID                = 0x1f,
  737         NVME_SC_INVALID_SEC_CTRLR_STATE         = 0x20,
  738         NVME_SC_INVALID_NUM_OF_CTRLR_RESRC      = 0x21,
  739         NVME_SC_INVALID_RESOURCE_ID             = 0x22,
  740         NVME_SC_SANITIZE_PROHIBITED_WPMRE       = 0x23,
  741         NVME_SC_ANA_GROUP_ID_INVALID            = 0x24,
  742         NVME_SC_ANA_ATTACH_FAILED               = 0x25,
  743 
  744         NVME_SC_CONFLICTING_ATTRIBUTES          = 0x80,
  745         NVME_SC_INVALID_PROTECTION_INFO         = 0x81,
  746         NVME_SC_ATTEMPTED_WRITE_TO_RO_PAGE      = 0x82,
  747 };
  748 
  749 /* media error status codes */
  750 enum nvme_media_error_status_code {
  751         NVME_SC_WRITE_FAULTS                    = 0x80,
  752         NVME_SC_UNRECOVERED_READ_ERROR          = 0x81,
  753         NVME_SC_GUARD_CHECK_ERROR               = 0x82,
  754         NVME_SC_APPLICATION_TAG_CHECK_ERROR     = 0x83,
  755         NVME_SC_REFERENCE_TAG_CHECK_ERROR       = 0x84,
  756         NVME_SC_COMPARE_FAILURE                 = 0x85,
  757         NVME_SC_ACCESS_DENIED                   = 0x86,
  758         NVME_SC_DEALLOCATED_OR_UNWRITTEN        = 0x87,
  759 };
  760 
  761 /* path related status codes */
  762 enum nvme_path_related_status_code {
  763         NVME_SC_INTERNAL_PATH_ERROR             = 0x00,
  764         NVME_SC_ASYMMETRIC_ACCESS_PERSISTENT_LOSS = 0x01,
  765         NVME_SC_ASYMMETRIC_ACCESS_INACCESSIBLE  = 0x02,
  766         NVME_SC_ASYMMETRIC_ACCESS_TRANSITION    = 0x03,
  767         NVME_SC_CONTROLLER_PATHING_ERROR        = 0x60,
  768         NVME_SC_HOST_PATHING_ERROR              = 0x70,
  769         NVME_SC_COMMAND_ABOTHED_BY_HOST         = 0x71,
  770 };
  771 
  772 /* admin opcodes */
  773 enum nvme_admin_opcode {
  774         NVME_OPC_DELETE_IO_SQ                   = 0x00,
  775         NVME_OPC_CREATE_IO_SQ                   = 0x01,
  776         NVME_OPC_GET_LOG_PAGE                   = 0x02,
  777         /* 0x03 - reserved */
  778         NVME_OPC_DELETE_IO_CQ                   = 0x04,
  779         NVME_OPC_CREATE_IO_CQ                   = 0x05,
  780         NVME_OPC_IDENTIFY                       = 0x06,
  781         /* 0x07 - reserved */
  782         NVME_OPC_ABORT                          = 0x08,
  783         NVME_OPC_SET_FEATURES                   = 0x09,
  784         NVME_OPC_GET_FEATURES                   = 0x0a,
  785         /* 0x0b - reserved */
  786         NVME_OPC_ASYNC_EVENT_REQUEST            = 0x0c,
  787         NVME_OPC_NAMESPACE_MANAGEMENT           = 0x0d,
  788         /* 0x0e-0x0f - reserved */
  789         NVME_OPC_FIRMWARE_ACTIVATE              = 0x10,
  790         NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD        = 0x11,
  791         /* 0x12-0x13 - reserved */
  792         NVME_OPC_DEVICE_SELF_TEST               = 0x14,
  793         NVME_OPC_NAMESPACE_ATTACHMENT           = 0x15,
  794         /* 0x16-0x17 - reserved */
  795         NVME_OPC_KEEP_ALIVE                     = 0x18,
  796         NVME_OPC_DIRECTIVE_SEND                 = 0x19,
  797         NVME_OPC_DIRECTIVE_RECEIVE              = 0x1a,
  798         /* 0x1b - reserved */
  799         NVME_OPC_VIRTUALIZATION_MANAGEMENT      = 0x1c,
  800         NVME_OPC_NVME_MI_SEND                   = 0x1d,
  801         NVME_OPC_NVME_MI_RECEIVE                = 0x1e,
  802         /* 0x1f-0x7b - reserved */
  803         NVME_OPC_DOORBELL_BUFFER_CONFIG         = 0x7c,
  804 
  805         NVME_OPC_FORMAT_NVM                     = 0x80,
  806         NVME_OPC_SECURITY_SEND                  = 0x81,
  807         NVME_OPC_SECURITY_RECEIVE               = 0x82,
  808         /* 0x83 - reserved */
  809         NVME_OPC_SANITIZE                       = 0x84,
  810         /* 0x85 - reserved */
  811         NVME_OPC_GET_LBA_STATUS                 = 0x86,
  812 };
  813 
  814 /* nvme nvm opcodes */
  815 enum nvme_nvm_opcode {
  816         NVME_OPC_FLUSH                          = 0x00,
  817         NVME_OPC_WRITE                          = 0x01,
  818         NVME_OPC_READ                           = 0x02,
  819         /* 0x03 - reserved */
  820         NVME_OPC_WRITE_UNCORRECTABLE            = 0x04,
  821         NVME_OPC_COMPARE                        = 0x05,
  822         /* 0x06-0x07 - reserved */
  823         NVME_OPC_WRITE_ZEROES                   = 0x08,
  824         NVME_OPC_DATASET_MANAGEMENT             = 0x09,
  825         /* 0x0a-0x0b - reserved */
  826         NVME_OPC_VERIFY                         = 0x0c,
  827         NVME_OPC_RESERVATION_REGISTER           = 0x0d,
  828         NVME_OPC_RESERVATION_REPORT             = 0x0e,
  829         /* 0x0f-0x10 - reserved */
  830         NVME_OPC_RESERVATION_ACQUIRE            = 0x11,
  831         /* 0x12-0x14 - reserved */
  832         NVME_OPC_RESERVATION_RELEASE            = 0x15,
  833 };
  834 
  835 enum nvme_feature {
  836         /* 0x00 - reserved */
  837         NVME_FEAT_ARBITRATION                   = 0x01,
  838         NVME_FEAT_POWER_MANAGEMENT              = 0x02,
  839         NVME_FEAT_LBA_RANGE_TYPE                = 0x03,
  840         NVME_FEAT_TEMPERATURE_THRESHOLD         = 0x04,
  841         NVME_FEAT_ERROR_RECOVERY                = 0x05,
  842         NVME_FEAT_VOLATILE_WRITE_CACHE          = 0x06,
  843         NVME_FEAT_NUMBER_OF_QUEUES              = 0x07,
  844         NVME_FEAT_INTERRUPT_COALESCING          = 0x08,
  845         NVME_FEAT_INTERRUPT_VECTOR_CONFIGURATION = 0x09,
  846         NVME_FEAT_WRITE_ATOMICITY               = 0x0A,
  847         NVME_FEAT_ASYNC_EVENT_CONFIGURATION     = 0x0B,
  848         NVME_FEAT_AUTONOMOUS_POWER_STATE_TRANSITION = 0x0C,
  849         NVME_FEAT_HOST_MEMORY_BUFFER            = 0x0D,
  850         NVME_FEAT_TIMESTAMP                     = 0x0E,
  851         NVME_FEAT_KEEP_ALIVE_TIMER              = 0x0F,
  852         NVME_FEAT_HOST_CONTROLLED_THERMAL_MGMT  = 0x10,
  853         NVME_FEAT_NON_OP_POWER_STATE_CONFIG     = 0x11,
  854         NVME_FEAT_READ_RECOVERY_LEVEL_CONFIG    = 0x12,
  855         NVME_FEAT_PREDICTABLE_LATENCY_MODE_CONFIG = 0x13,
  856         NVME_FEAT_PREDICTABLE_LATENCY_MODE_WINDOW = 0x14,
  857         NVME_FEAT_LBA_STATUS_INFORMATION_ATTRIBUTES = 0x15,
  858         NVME_FEAT_HOST_BEHAVIOR_SUPPORT         = 0x16,
  859         NVME_FEAT_SANITIZE_CONFIG               = 0x17,
  860         NVME_FEAT_ENDURANCE_GROUP_EVENT_CONFIGURATION = 0x18,
  861         /* 0x19-0x77 - reserved */
  862         /* 0x78-0x7f - NVMe Management Interface */
  863         NVME_FEAT_SOFTWARE_PROGRESS_MARKER      = 0x80,
  864         NVME_FEAT_HOST_IDENTIFIER               = 0x81,
  865         NVME_FEAT_RESERVATION_NOTIFICATION_MASK = 0x82,
  866         NVME_FEAT_RESERVATION_PERSISTENCE       = 0x83,
  867         NVME_FEAT_NAMESPACE_WRITE_PROTECTION_CONFIG = 0x84,
  868         /* 0x85-0xBF - command set specific (reserved) */
  869         /* 0xC0-0xFF - vendor specific */
  870 };
  871 
  872 enum nvme_dsm_attribute {
  873         NVME_DSM_ATTR_INTEGRAL_READ             = 0x1,
  874         NVME_DSM_ATTR_INTEGRAL_WRITE            = 0x2,
  875         NVME_DSM_ATTR_DEALLOCATE                = 0x4,
  876 };
  877 
  878 enum nvme_activate_action {
  879         NVME_AA_REPLACE_NO_ACTIVATE             = 0x0,
  880         NVME_AA_REPLACE_ACTIVATE                = 0x1,
  881         NVME_AA_ACTIVATE                        = 0x2,
  882 };
  883 
  884 struct nvme_power_state {
  885         /** Maximum Power */
  886         uint16_t        mp;                     /* Maximum Power */
  887         uint8_t         ps_rsvd1;
  888         uint8_t         mps_nops;               /* Max Power Scale, Non-Operational State */
  889 
  890         uint32_t        enlat;                  /* Entry Latency */
  891         uint32_t        exlat;                  /* Exit Latency */
  892 
  893         uint8_t         rrt;                    /* Relative Read Throughput */
  894         uint8_t         rrl;                    /* Relative Read Latency */
  895         uint8_t         rwt;                    /* Relative Write Throughput */
  896         uint8_t         rwl;                    /* Relative Write Latency */
  897 
  898         uint16_t        idlp;                   /* Idle Power */
  899         uint8_t         ips;                    /* Idle Power Scale */
  900         uint8_t         ps_rsvd8;
  901 
  902         uint16_t        actp;                   /* Active Power */
  903         uint8_t         apw_aps;                /* Active Power Workload, Active Power Scale */
  904         uint8_t         ps_rsvd10[9];
  905 } __packed;
  906 
  907 _Static_assert(sizeof(struct nvme_power_state) == 32, "bad size for nvme_power_state");
  908 
  909 #define NVME_SERIAL_NUMBER_LENGTH       20
  910 #define NVME_MODEL_NUMBER_LENGTH        40
  911 #define NVME_FIRMWARE_REVISION_LENGTH   8
  912 
  913 struct nvme_controller_data {
  914         /* bytes 0-255: controller capabilities and features */
  915 
  916         /** pci vendor id */
  917         uint16_t                vid;
  918 
  919         /** pci subsystem vendor id */
  920         uint16_t                ssvid;
  921 
  922         /** serial number */
  923         uint8_t                 sn[NVME_SERIAL_NUMBER_LENGTH];
  924 
  925         /** model number */
  926         uint8_t                 mn[NVME_MODEL_NUMBER_LENGTH];
  927 
  928         /** firmware revision */
  929         uint8_t                 fr[NVME_FIRMWARE_REVISION_LENGTH];
  930 
  931         /** recommended arbitration burst */
  932         uint8_t                 rab;
  933 
  934         /** ieee oui identifier */
  935         uint8_t                 ieee[3];
  936 
  937         /** multi-interface capabilities */
  938         uint8_t                 mic;
  939 
  940         /** maximum data transfer size */
  941         uint8_t                 mdts;
  942 
  943         /** Controller ID */
  944         uint16_t                ctrlr_id;
  945 
  946         /** Version */
  947         uint32_t                ver;
  948 
  949         /** RTD3 Resume Latency */
  950         uint32_t                rtd3r;
  951 
  952         /** RTD3 Enter Latency */
  953         uint32_t                rtd3e;
  954 
  955         /** Optional Asynchronous Events Supported */
  956         uint32_t                oaes;   /* bitfield really */
  957 
  958         /** Controller Attributes */
  959         uint32_t                ctratt; /* bitfield really */
  960 
  961         /** Read Recovery Levels Supported */
  962         uint16_t                rrls;
  963 
  964         uint8_t                 reserved1[9];
  965 
  966         /** Controller Type */
  967         uint8_t                 cntrltype;
  968 
  969         /** FRU Globally Unique Identifier */
  970         uint8_t                 fguid[16];
  971 
  972         /** Command Retry Delay Time 1 */
  973         uint16_t                crdt1;
  974 
  975         /** Command Retry Delay Time 2 */
  976         uint16_t                crdt2;
  977 
  978         /** Command Retry Delay Time 3 */
  979         uint16_t                crdt3;
  980 
  981         uint8_t                 reserved2[122];
  982 
  983         /* bytes 256-511: admin command set attributes */
  984 
  985         /** optional admin command support */
  986         uint16_t                oacs;
  987 
  988         /** abort command limit */
  989         uint8_t                 acl;
  990 
  991         /** asynchronous event request limit */
  992         uint8_t                 aerl;
  993 
  994         /** firmware updates */
  995         uint8_t                 frmw;
  996 
  997         /** log page attributes */
  998         uint8_t                 lpa;
  999 
 1000         /** error log page entries */
 1001         uint8_t                 elpe;
 1002 
 1003         /** number of power states supported */
 1004         uint8_t                 npss;
 1005 
 1006         /** admin vendor specific command configuration */
 1007         uint8_t                 avscc;
 1008 
 1009         /** Autonomous Power State Transition Attributes */
 1010         uint8_t                 apsta;
 1011 
 1012         /** Warning Composite Temperature Threshold */
 1013         uint16_t                wctemp;
 1014 
 1015         /** Critical Composite Temperature Threshold */
 1016         uint16_t                cctemp;
 1017 
 1018         /** Maximum Time for Firmware Activation */
 1019         uint16_t                mtfa;
 1020 
 1021         /** Host Memory Buffer Preferred Size */
 1022         uint32_t                hmpre;
 1023 
 1024         /** Host Memory Buffer Minimum Size */
 1025         uint32_t                hmmin;
 1026 
 1027         /** Name space capabilities  */
 1028         struct {
 1029                 /* if nsmgmt, report tnvmcap and unvmcap */
 1030                 uint8_t    tnvmcap[16];
 1031                 uint8_t    unvmcap[16];
 1032         } __packed untncap;
 1033 
 1034         /** Replay Protected Memory Block Support */
 1035         uint32_t                rpmbs; /* Really a bitfield */
 1036 
 1037         /** Extended Device Self-test Time */
 1038         uint16_t                edstt;
 1039 
 1040         /** Device Self-test Options */
 1041         uint8_t                 dsto; /* Really a bitfield */
 1042 
 1043         /** Firmware Update Granularity */
 1044         uint8_t                 fwug;
 1045 
 1046         /** Keep Alive Support */
 1047         uint16_t                kas;
 1048 
 1049         /** Host Controlled Thermal Management Attributes */
 1050         uint16_t                hctma; /* Really a bitfield */
 1051 
 1052         /** Minimum Thermal Management Temperature */
 1053         uint16_t                mntmt;
 1054 
 1055         /** Maximum Thermal Management Temperature */
 1056         uint16_t                mxtmt;
 1057 
 1058         /** Sanitize Capabilities */
 1059         uint32_t                sanicap; /* Really a bitfield */
 1060 
 1061         /** Host Memory Buffer Minimum Descriptor Entry Size */
 1062         uint32_t                hmminds;
 1063 
 1064         /** Host Memory Maximum Descriptors Entries */
 1065         uint16_t                hmmaxd;
 1066 
 1067         /** NVM Set Identifier Maximum */
 1068         uint16_t                nsetidmax;
 1069 
 1070         /** Endurance Group Identifier Maximum */
 1071         uint16_t                endgidmax;
 1072 
 1073         /** ANA Transition Time */
 1074         uint8_t                 anatt;
 1075 
 1076         /** Asymmetric Namespace Access Capabilities */
 1077         uint8_t                 anacap;
 1078 
 1079         /** ANA Group Identifier Maximum */
 1080         uint32_t                anagrpmax;
 1081 
 1082         /** Number of ANA Group Identifiers */
 1083         uint32_t                nanagrpid;
 1084 
 1085         /** Persistent Event Log Size */
 1086         uint32_t                pels;
 1087 
 1088         uint8_t                 reserved3[156];
 1089         /* bytes 512-703: nvm command set attributes */
 1090 
 1091         /** submission queue entry size */
 1092         uint8_t                 sqes;
 1093 
 1094         /** completion queue entry size */
 1095         uint8_t                 cqes;
 1096 
 1097         /** Maximum Outstanding Commands */
 1098         uint16_t                maxcmd;
 1099 
 1100         /** number of namespaces */
 1101         uint32_t                nn;
 1102 
 1103         /** optional nvm command support */
 1104         uint16_t                oncs;
 1105 
 1106         /** fused operation support */
 1107         uint16_t                fuses;
 1108 
 1109         /** format nvm attributes */
 1110         uint8_t                 fna;
 1111 
 1112         /** volatile write cache */
 1113         uint8_t                 vwc;
 1114 
 1115         /** Atomic Write Unit Normal */
 1116         uint16_t                awun;
 1117 
 1118         /** Atomic Write Unit Power Fail */
 1119         uint16_t                awupf;
 1120 
 1121         /** NVM Vendor Specific Command Configuration */
 1122         uint8_t                 nvscc;
 1123 
 1124         /** Namespace Write Protection Capabilities */
 1125         uint8_t                 nwpc;
 1126 
 1127         /** Atomic Compare & Write Unit */
 1128         uint16_t                acwu;
 1129         uint16_t                reserved6;
 1130 
 1131         /** SGL Support */
 1132         uint32_t                sgls;
 1133 
 1134         /** Maximum Number of Allowed Namespaces */
 1135         uint32_t                mnan;
 1136 
 1137         /* bytes 540-767: Reserved */
 1138         uint8_t                 reserved7[224];
 1139 
 1140         /** NVM Subsystem NVMe Qualified Name */
 1141         uint8_t                 subnqn[256];
 1142 
 1143         /* bytes 1024-1791: Reserved */
 1144         uint8_t                 reserved8[768];
 1145 
 1146         /* bytes 1792-2047: NVMe over Fabrics specification */
 1147         uint8_t                 reserved9[256];
 1148 
 1149         /* bytes 2048-3071: power state descriptors */
 1150         struct nvme_power_state power_state[32];
 1151 
 1152         /* bytes 3072-4095: vendor specific */
 1153         uint8_t                 vs[1024];
 1154 } __packed __aligned(4);
 1155 
 1156 _Static_assert(sizeof(struct nvme_controller_data) == 4096, "bad size for nvme_controller_data");
 1157 
 1158 struct nvme_namespace_data {
 1159         /** namespace size */
 1160         uint64_t                nsze;
 1161 
 1162         /** namespace capacity */
 1163         uint64_t                ncap;
 1164 
 1165         /** namespace utilization */
 1166         uint64_t                nuse;
 1167 
 1168         /** namespace features */
 1169         uint8_t                 nsfeat;
 1170 
 1171         /** number of lba formats */
 1172         uint8_t                 nlbaf;
 1173 
 1174         /** formatted lba size */
 1175         uint8_t                 flbas;
 1176 
 1177         /** metadata capabilities */
 1178         uint8_t                 mc;
 1179 
 1180         /** end-to-end data protection capabilities */
 1181         uint8_t                 dpc;
 1182 
 1183         /** end-to-end data protection type settings */
 1184         uint8_t                 dps;
 1185 
 1186         /** Namespace Multi-path I/O and Namespace Sharing Capabilities */
 1187         uint8_t                 nmic;
 1188 
 1189         /** Reservation Capabilities */
 1190         uint8_t                 rescap;
 1191 
 1192         /** Format Progress Indicator */
 1193         uint8_t                 fpi;
 1194 
 1195         /** Deallocate Logical Block Features */
 1196         uint8_t                 dlfeat;
 1197 
 1198         /** Namespace Atomic Write Unit Normal  */
 1199         uint16_t                nawun;
 1200 
 1201         /** Namespace Atomic Write Unit Power Fail */
 1202         uint16_t                nawupf;
 1203 
 1204         /** Namespace Atomic Compare & Write Unit */
 1205         uint16_t                nacwu;
 1206 
 1207         /** Namespace Atomic Boundary Size Normal */
 1208         uint16_t                nabsn;
 1209 
 1210         /** Namespace Atomic Boundary Offset */
 1211         uint16_t                nabo;
 1212 
 1213         /** Namespace Atomic Boundary Size Power Fail */
 1214         uint16_t                nabspf;
 1215 
 1216         /** Namespace Optimal IO Boundary */
 1217         uint16_t                noiob;
 1218 
 1219         /** NVM Capacity */
 1220         uint8_t                 nvmcap[16];
 1221 
 1222         /** Namespace Preferred Write Granularity  */
 1223         uint16_t                npwg;
 1224 
 1225         /** Namespace Preferred Write Alignment */
 1226         uint16_t                npwa;
 1227 
 1228         /** Namespace Preferred Deallocate Granularity */
 1229         uint16_t                npdg;
 1230 
 1231         /** Namespace Preferred Deallocate Alignment */
 1232         uint16_t                npda;
 1233 
 1234         /** Namespace Optimal Write Size */
 1235         uint16_t                nows;
 1236 
 1237         /* bytes 74-91: Reserved */
 1238         uint8_t                 reserved5[18];
 1239 
 1240         /** ANA Group Identifier */
 1241         uint32_t                anagrpid;
 1242 
 1243         /* bytes 96-98: Reserved */
 1244         uint8_t                 reserved6[3];
 1245 
 1246         /** Namespace Attributes */
 1247         uint8_t                 nsattr;
 1248 
 1249         /** NVM Set Identifier */
 1250         uint16_t                nvmsetid;
 1251 
 1252         /** Endurance Group Identifier */
 1253         uint16_t                endgid;
 1254 
 1255         /** Namespace Globally Unique Identifier */
 1256         uint8_t                 nguid[16];
 1257 
 1258         /** IEEE Extended Unique Identifier */
 1259         uint8_t                 eui64[8];
 1260 
 1261         /** lba format support */
 1262         uint32_t                lbaf[16];
 1263 
 1264         uint8_t                 reserved7[192];
 1265 
 1266         uint8_t                 vendor_specific[3712];
 1267 } __packed __aligned(4);
 1268 
 1269 _Static_assert(sizeof(struct nvme_namespace_data) == 4096, "bad size for nvme_namepsace_data");
 1270 
 1271 enum nvme_log_page {
 1272         /* 0x00 - reserved */
 1273         NVME_LOG_ERROR                  = 0x01,
 1274         NVME_LOG_HEALTH_INFORMATION     = 0x02,
 1275         NVME_LOG_FIRMWARE_SLOT          = 0x03,
 1276         NVME_LOG_CHANGED_NAMESPACE      = 0x04,
 1277         NVME_LOG_COMMAND_EFFECT         = 0x05,
 1278         NVME_LOG_DEVICE_SELF_TEST       = 0x06,
 1279         NVME_LOG_TELEMETRY_HOST_INITIATED = 0x07,
 1280         NVME_LOG_TELEMETRY_CONTROLLER_INITIATED = 0x08,
 1281         NVME_LOG_ENDURANCE_GROUP_INFORMATION = 0x09,
 1282         NVME_LOG_PREDICTABLE_LATENCY_PER_NVM_SET = 0x0a,
 1283         NVME_LOG_PREDICTABLE_LATENCY_EVENT_AGGREGATE = 0x0b,
 1284         NVME_LOG_ASYMMETRIC_NAMESPAVE_ACCESS = 0x0c,
 1285         NVME_LOG_PERSISTENT_EVENT_LOG   = 0x0d,
 1286         NVME_LOG_LBA_STATUS_INFORMATION = 0x0e,
 1287         NVME_LOG_ENDURANCE_GROUP_EVENT_AGGREGATE = 0x0f,
 1288         /* 0x06-0x7F - reserved */
 1289         /* 0x80-0xBF - I/O command set specific */
 1290         NVME_LOG_RES_NOTIFICATION       = 0x80,
 1291         NVME_LOG_SANITIZE_STATUS        = 0x81,
 1292         /* 0x82-0xBF - reserved */
 1293         /* 0xC0-0xFF - vendor specific */
 1294 
 1295         /*
 1296          * The following are Intel Specific log pages, but they seem
 1297          * to be widely implemented.
 1298          */
 1299         INTEL_LOG_READ_LAT_LOG          = 0xc1,
 1300         INTEL_LOG_WRITE_LAT_LOG         = 0xc2,
 1301         INTEL_LOG_TEMP_STATS            = 0xc5,
 1302         INTEL_LOG_ADD_SMART             = 0xca,
 1303         INTEL_LOG_DRIVE_MKT_NAME        = 0xdd,
 1304 
 1305         /*
 1306          * HGST log page, with lots ofs sub pages.
 1307          */
 1308         HGST_INFO_LOG                   = 0xc1,
 1309 };
 1310 
 1311 struct nvme_error_information_entry {
 1312         uint64_t                error_count;
 1313         uint16_t                sqid;
 1314         uint16_t                cid;
 1315         uint16_t                status;
 1316         uint16_t                error_location;
 1317         uint64_t                lba;
 1318         uint32_t                nsid;
 1319         uint8_t                 vendor_specific;
 1320         uint8_t                 trtype;
 1321         uint16_t                reserved30;
 1322         uint64_t                csi;
 1323         uint16_t                ttsi;
 1324         uint8_t                 reserved[22];
 1325 } __packed __aligned(4);
 1326 
 1327 _Static_assert(sizeof(struct nvme_error_information_entry) == 64, "bad size for nvme_error_information_entry");
 1328 
 1329 struct nvme_health_information_page {
 1330         uint8_t                 critical_warning;
 1331         uint16_t                temperature;
 1332         uint8_t                 available_spare;
 1333         uint8_t                 available_spare_threshold;
 1334         uint8_t                 percentage_used;
 1335 
 1336         uint8_t                 reserved[26];
 1337 
 1338         /*
 1339          * Note that the following are 128-bit values, but are
 1340          *  defined as an array of 2 64-bit values.
 1341          */
 1342         /* Data Units Read is always in 512-byte units. */
 1343         uint64_t                data_units_read[2];
 1344         /* Data Units Written is always in 512-byte units. */
 1345         uint64_t                data_units_written[2];
 1346         /* For NVM command set, this includes Compare commands. */
 1347         uint64_t                host_read_commands[2];
 1348         uint64_t                host_write_commands[2];
 1349         /* Controller Busy Time is reported in minutes. */
 1350         uint64_t                controller_busy_time[2];
 1351         uint64_t                power_cycles[2];
 1352         uint64_t                power_on_hours[2];
 1353         uint64_t                unsafe_shutdowns[2];
 1354         uint64_t                media_errors[2];
 1355         uint64_t                num_error_info_log_entries[2];
 1356         uint32_t                warning_temp_time;
 1357         uint32_t                error_temp_time;
 1358         uint16_t                temp_sensor[8];
 1359         /* Thermal Management Temperature 1 Transition Count */
 1360         uint32_t                tmt1tc;
 1361         /* Thermal Management Temperature 2 Transition Count */
 1362         uint32_t                tmt2tc;
 1363         /* Total Time For Thermal Management Temperature 1 */
 1364         uint32_t                ttftmt1;
 1365         /* Total Time For Thermal Management Temperature 2 */
 1366         uint32_t                ttftmt2;
 1367 
 1368         uint8_t                 reserved2[280];
 1369 } __packed __aligned(4);
 1370 
 1371 _Static_assert(sizeof(struct nvme_health_information_page) == 512, "bad size for nvme_health_information_page");
 1372 
 1373 struct nvme_firmware_page {
 1374         uint8_t                 afi;
 1375         uint8_t                 reserved[7];
 1376         uint64_t                revision[7]; /* revisions for 7 slots */
 1377         uint8_t                 reserved2[448];
 1378 } __packed __aligned(4);
 1379 
 1380 _Static_assert(sizeof(struct nvme_firmware_page) == 512, "bad size for nvme_firmware_page");
 1381 
 1382 struct nvme_ns_list {
 1383         uint32_t                ns[1024];
 1384 } __packed __aligned(4);
 1385 
 1386 _Static_assert(sizeof(struct nvme_ns_list) == 4096, "bad size for nvme_ns_list");
 1387 
 1388 struct nvme_command_effects_page {
 1389         uint32_t                acs[256];
 1390         uint32_t                iocs[256];
 1391         uint8_t                 reserved[2048];
 1392 } __packed __aligned(4);
 1393 
 1394 _Static_assert(sizeof(struct nvme_command_effects_page) == 4096,
 1395     "bad size for nvme_command_effects_page");
 1396 
 1397 struct nvme_device_self_test_page {
 1398         uint8_t                 curr_operation;
 1399         uint8_t                 curr_compl;
 1400         uint8_t                 rsvd2[2];
 1401         struct {
 1402                 uint8_t         status;
 1403                 uint8_t         segment_num;
 1404                 uint8_t         valid_diag_info;
 1405                 uint8_t         rsvd3;
 1406                 uint64_t        poh;
 1407                 uint32_t        nsid;
 1408                 /* Define as an array to simplify alignment issues */
 1409                 uint8_t         failing_lba[8];
 1410                 uint8_t         status_code_type;
 1411                 uint8_t         status_code;
 1412                 uint8_t         vendor_specific[2];
 1413         } __packed result[20];
 1414 } __packed __aligned(4);
 1415 
 1416 _Static_assert(sizeof(struct nvme_device_self_test_page) == 564,
 1417     "bad size for nvme_device_self_test_page");
 1418 
 1419 struct nvme_res_notification_page {
 1420         uint64_t                log_page_count;
 1421         uint8_t                 log_page_type;
 1422         uint8_t                 available_log_pages;
 1423         uint8_t                 reserved2;
 1424         uint32_t                nsid;
 1425         uint8_t                 reserved[48];
 1426 } __packed __aligned(4);
 1427 
 1428 _Static_assert(sizeof(struct nvme_res_notification_page) == 64,
 1429     "bad size for nvme_res_notification_page");
 1430 
 1431 struct nvme_sanitize_status_page {
 1432         uint16_t                sprog;
 1433         uint16_t                sstat;
 1434         uint32_t                scdw10;
 1435         uint32_t                etfo;
 1436         uint32_t                etfbe;
 1437         uint32_t                etfce;
 1438         uint32_t                etfownd;
 1439         uint32_t                etfbewnd;
 1440         uint32_t                etfcewnd;
 1441         uint8_t                 reserved[480];
 1442 } __packed __aligned(4);
 1443 
 1444 _Static_assert(sizeof(struct nvme_sanitize_status_page) == 512,
 1445     "bad size for nvme_sanitize_status_page");
 1446 
 1447 struct intel_log_temp_stats {
 1448         uint64_t        current;
 1449         uint64_t        overtemp_flag_last;
 1450         uint64_t        overtemp_flag_life;
 1451         uint64_t        max_temp;
 1452         uint64_t        min_temp;
 1453         uint64_t        _rsvd[5];
 1454         uint64_t        max_oper_temp;
 1455         uint64_t        min_oper_temp;
 1456         uint64_t        est_offset;
 1457 } __packed __aligned(4);
 1458 
 1459 _Static_assert(sizeof(struct intel_log_temp_stats) == 13 * 8, "bad size for intel_log_temp_stats");
 1460 
 1461 struct nvme_resv_reg_ctrlr {
 1462         uint16_t                ctrlr_id;       /* Controller ID */
 1463         uint8_t                 rcsts;          /* Reservation Status */
 1464         uint8_t                 reserved3[5];
 1465         uint64_t                hostid;         /* Host Identifier */
 1466         uint64_t                rkey;           /* Reservation Key */
 1467 } __packed __aligned(4);
 1468 
 1469 _Static_assert(sizeof(struct nvme_resv_reg_ctrlr) == 24, "bad size for nvme_resv_reg_ctrlr");
 1470 
 1471 struct nvme_resv_reg_ctrlr_ext {
 1472         uint16_t                ctrlr_id;       /* Controller ID */
 1473         uint8_t                 rcsts;          /* Reservation Status */
 1474         uint8_t                 reserved3[5];
 1475         uint64_t                rkey;           /* Reservation Key */
 1476         uint64_t                hostid[2];      /* Host Identifier */
 1477         uint8_t                 reserved32[32];
 1478 } __packed __aligned(4);
 1479 
 1480 _Static_assert(sizeof(struct nvme_resv_reg_ctrlr_ext) == 64, "bad size for nvme_resv_reg_ctrlr_ext");
 1481 
 1482 struct nvme_resv_status {
 1483         uint32_t                gen;            /* Generation */
 1484         uint8_t                 rtype;          /* Reservation Type */
 1485         uint8_t                 regctl[2];      /* Number of Registered Controllers */
 1486         uint8_t                 reserved7[2];
 1487         uint8_t                 ptpls;          /* Persist Through Power Loss State */
 1488         uint8_t                 reserved10[14];
 1489         struct nvme_resv_reg_ctrlr      ctrlr[0];
 1490 } __packed __aligned(4);
 1491 
 1492 _Static_assert(sizeof(struct nvme_resv_status) == 24, "bad size for nvme_resv_status");
 1493 
 1494 struct nvme_resv_status_ext {
 1495         uint32_t                gen;            /* Generation */
 1496         uint8_t                 rtype;          /* Reservation Type */
 1497         uint8_t                 regctl[2];      /* Number of Registered Controllers */
 1498         uint8_t                 reserved7[2];
 1499         uint8_t                 ptpls;          /* Persist Through Power Loss State */
 1500         uint8_t                 reserved10[14];
 1501         uint8_t                 reserved24[40];
 1502         struct nvme_resv_reg_ctrlr_ext  ctrlr[0];
 1503 } __packed __aligned(4);
 1504 
 1505 _Static_assert(sizeof(struct nvme_resv_status_ext) == 64, "bad size for nvme_resv_status_ext");
 1506 
 1507 #define NVME_TEST_MAX_THREADS   128
 1508 
 1509 struct nvme_io_test {
 1510         enum nvme_nvm_opcode    opc;
 1511         uint32_t                size;
 1512         uint32_t                time;   /* in seconds */
 1513         uint32_t                num_threads;
 1514         uint32_t                flags;
 1515         uint64_t                io_completed[NVME_TEST_MAX_THREADS];
 1516 };
 1517 
 1518 enum nvme_io_test_flags {
 1519         /*
 1520          * Specifies whether dev_refthread/dev_relthread should be
 1521          *  called during NVME_BIO_TEST.  Ignored for other test
 1522          *  types.
 1523          */
 1524         NVME_TEST_FLAG_REFTHREAD =      0x1,
 1525 };
 1526 
 1527 struct nvme_pt_command {
 1528         /*
 1529          * cmd is used to specify a passthrough command to a controller or
 1530          *  namespace.
 1531          *
 1532          * The following fields from cmd may be specified by the caller:
 1533          *      * opc  (opcode)
 1534          *      * nsid (namespace id) - for admin commands only
 1535          *      * cdw10-cdw15
 1536          *
 1537          * Remaining fields must be set to 0 by the caller.
 1538          */
 1539         struct nvme_command     cmd;
 1540 
 1541         /*
 1542          * cpl returns completion status for the passthrough command
 1543          *  specified by cmd.
 1544          *
 1545          * The following fields will be filled out by the driver, for
 1546          *  consumption by the caller:
 1547          *      * cdw0
 1548          *      * status (except for phase)
 1549          *
 1550          * Remaining fields will be set to 0 by the driver.
 1551          */
 1552         struct nvme_completion  cpl;
 1553 
 1554         /* buf is the data buffer associated with this passthrough command. */
 1555         void *                  buf;
 1556 
 1557         /*
 1558          * len is the length of the data buffer associated with this
 1559          *  passthrough command.
 1560          */
 1561         uint32_t                len;
 1562 
 1563         /*
 1564          * is_read = 1 if the passthrough command will read data into the
 1565          *  supplied buffer from the controller.
 1566          *
 1567          * is_read = 0 if the passthrough command will write data from the
 1568          *  supplied buffer to the controller.
 1569          */
 1570         uint32_t                is_read;
 1571 
 1572         /*
 1573          * driver_lock is used by the driver only.  It must be set to 0
 1574          *  by the caller.
 1575          */
 1576         struct mtx *            driver_lock;
 1577 };
 1578 
 1579 struct nvme_get_nsid {
 1580         char            cdev[SPECNAMELEN + 1];
 1581         uint32_t        nsid;
 1582 };
 1583 
 1584 struct nvme_hmb_desc {
 1585         uint64_t        addr;
 1586         uint32_t        size;
 1587         uint32_t        reserved;
 1588 };
 1589 
 1590 #define nvme_completion_is_error(cpl)                                   \
 1591         (NVME_STATUS_GET_SC((cpl)->status) != 0 || NVME_STATUS_GET_SCT((cpl)->status) != 0)
 1592 
 1593 void    nvme_strvis(uint8_t *dst, const uint8_t *src, int dstlen, int srclen);
 1594 
 1595 #ifdef _KERNEL
 1596 
 1597 struct bio;
 1598 struct thread;
 1599 
 1600 struct nvme_namespace;
 1601 struct nvme_controller;
 1602 struct nvme_consumer;
 1603 
 1604 typedef void (*nvme_cb_fn_t)(void *, const struct nvme_completion *);
 1605 
 1606 typedef void *(*nvme_cons_ns_fn_t)(struct nvme_namespace *, void *);
 1607 typedef void *(*nvme_cons_ctrlr_fn_t)(struct nvme_controller *);
 1608 typedef void (*nvme_cons_async_fn_t)(void *, const struct nvme_completion *,
 1609                                      uint32_t, void *, uint32_t);
 1610 typedef void (*nvme_cons_fail_fn_t)(void *);
 1611 
 1612 enum nvme_namespace_flags {
 1613         NVME_NS_DEALLOCATE_SUPPORTED    = 0x1,
 1614         NVME_NS_FLUSH_SUPPORTED         = 0x2,
 1615 };
 1616 
 1617 int     nvme_ctrlr_passthrough_cmd(struct nvme_controller *ctrlr,
 1618                                    struct nvme_pt_command *pt,
 1619                                    uint32_t nsid, int is_user_buffer,
 1620                                    int is_admin_cmd);
 1621 
 1622 /* Admin functions */
 1623 void    nvme_ctrlr_cmd_set_feature(struct nvme_controller *ctrlr,
 1624                                    uint8_t feature, uint32_t cdw11,
 1625                                    uint32_t cdw12, uint32_t cdw13,
 1626                                    uint32_t cdw14, uint32_t cdw15,
 1627                                    void *payload, uint32_t payload_size,
 1628                                    nvme_cb_fn_t cb_fn, void *cb_arg);
 1629 void    nvme_ctrlr_cmd_get_feature(struct nvme_controller *ctrlr,
 1630                                    uint8_t feature, uint32_t cdw11,
 1631                                    void *payload, uint32_t payload_size,
 1632                                    nvme_cb_fn_t cb_fn, void *cb_arg);
 1633 void    nvme_ctrlr_cmd_get_log_page(struct nvme_controller *ctrlr,
 1634                                     uint8_t log_page, uint32_t nsid,
 1635                                     void *payload, uint32_t payload_size,
 1636                                     nvme_cb_fn_t cb_fn, void *cb_arg);
 1637 
 1638 /* NVM I/O functions */
 1639 int     nvme_ns_cmd_write(struct nvme_namespace *ns, void *payload,
 1640                           uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
 1641                           void *cb_arg);
 1642 int     nvme_ns_cmd_write_bio(struct nvme_namespace *ns, struct bio *bp,
 1643                               nvme_cb_fn_t cb_fn, void *cb_arg);
 1644 int     nvme_ns_cmd_read(struct nvme_namespace *ns, void *payload,
 1645                          uint64_t lba, uint32_t lba_count, nvme_cb_fn_t cb_fn,
 1646                          void *cb_arg);
 1647 int     nvme_ns_cmd_read_bio(struct nvme_namespace *ns, struct bio *bp,
 1648                               nvme_cb_fn_t cb_fn, void *cb_arg);
 1649 int     nvme_ns_cmd_deallocate(struct nvme_namespace *ns, void *payload,
 1650                                uint8_t num_ranges, nvme_cb_fn_t cb_fn,
 1651                                void *cb_arg);
 1652 int     nvme_ns_cmd_flush(struct nvme_namespace *ns, nvme_cb_fn_t cb_fn,
 1653                           void *cb_arg);
 1654 int     nvme_ns_dump(struct nvme_namespace *ns, void *virt, off_t offset,
 1655                      size_t len);
 1656 
 1657 /* Registration functions */
 1658 struct nvme_consumer *  nvme_register_consumer(nvme_cons_ns_fn_t    ns_fn,
 1659                                                nvme_cons_ctrlr_fn_t ctrlr_fn,
 1660                                                nvme_cons_async_fn_t async_fn,
 1661                                                nvme_cons_fail_fn_t  fail_fn);
 1662 void            nvme_unregister_consumer(struct nvme_consumer *consumer);
 1663 
 1664 /* Controller helper functions */
 1665 device_t        nvme_ctrlr_get_device(struct nvme_controller *ctrlr);
 1666 const struct nvme_controller_data *
 1667                 nvme_ctrlr_get_data(struct nvme_controller *ctrlr);
 1668 static inline bool
 1669 nvme_ctrlr_has_dataset_mgmt(const struct nvme_controller_data *cd)
 1670 {
 1671         /* Assumes cd was byte swapped by nvme_controller_data_swapbytes() */
 1672         return ((cd->oncs >> NVME_CTRLR_DATA_ONCS_DSM_SHIFT) &
 1673                 NVME_CTRLR_DATA_ONCS_DSM_MASK);
 1674 }
 1675 
 1676 /* Namespace helper functions */
 1677 uint32_t        nvme_ns_get_max_io_xfer_size(struct nvme_namespace *ns);
 1678 uint32_t        nvme_ns_get_sector_size(struct nvme_namespace *ns);
 1679 uint64_t        nvme_ns_get_num_sectors(struct nvme_namespace *ns);
 1680 uint64_t        nvme_ns_get_size(struct nvme_namespace *ns);
 1681 uint32_t        nvme_ns_get_flags(struct nvme_namespace *ns);
 1682 const char *    nvme_ns_get_serial_number(struct nvme_namespace *ns);
 1683 const char *    nvme_ns_get_model_number(struct nvme_namespace *ns);
 1684 const struct nvme_namespace_data *
 1685                 nvme_ns_get_data(struct nvme_namespace *ns);
 1686 uint32_t        nvme_ns_get_stripesize(struct nvme_namespace *ns);
 1687 
 1688 int     nvme_ns_bio_process(struct nvme_namespace *ns, struct bio *bp,
 1689                             nvme_cb_fn_t cb_fn);
 1690 int     nvme_ns_ioctl_process(struct nvme_namespace *ns, u_long cmd,
 1691     caddr_t arg, int flag, struct thread *td);
 1692 
 1693 /*
 1694  * Command building helper functions -- shared with CAM
 1695  * These functions assume allocator zeros out cmd structure
 1696  * CAM's xpt_get_ccb and the request allocator for nvme both
 1697  * do zero'd allocations.
 1698  */
 1699 static inline
 1700 void    nvme_ns_flush_cmd(struct nvme_command *cmd, uint32_t nsid)
 1701 {
 1702 
 1703         cmd->opc = NVME_OPC_FLUSH;
 1704         cmd->nsid = htole32(nsid);
 1705 }
 1706 
 1707 static inline
 1708 void    nvme_ns_rw_cmd(struct nvme_command *cmd, uint32_t rwcmd, uint32_t nsid,
 1709     uint64_t lba, uint32_t count)
 1710 {
 1711         cmd->opc = rwcmd;
 1712         cmd->nsid = htole32(nsid);
 1713         cmd->cdw10 = htole32(lba & 0xffffffffu);
 1714         cmd->cdw11 = htole32(lba >> 32);
 1715         cmd->cdw12 = htole32(count-1);
 1716 }
 1717 
 1718 static inline
 1719 void    nvme_ns_write_cmd(struct nvme_command *cmd, uint32_t nsid,
 1720     uint64_t lba, uint32_t count)
 1721 {
 1722         nvme_ns_rw_cmd(cmd, NVME_OPC_WRITE, nsid, lba, count);
 1723 }
 1724 
 1725 static inline
 1726 void    nvme_ns_read_cmd(struct nvme_command *cmd, uint32_t nsid,
 1727     uint64_t lba, uint32_t count)
 1728 {
 1729         nvme_ns_rw_cmd(cmd, NVME_OPC_READ, nsid, lba, count);
 1730 }
 1731 
 1732 static inline
 1733 void    nvme_ns_trim_cmd(struct nvme_command *cmd, uint32_t nsid,
 1734     uint32_t num_ranges)
 1735 {
 1736         cmd->opc = NVME_OPC_DATASET_MANAGEMENT;
 1737         cmd->nsid = htole32(nsid);
 1738         cmd->cdw10 = htole32(num_ranges - 1);
 1739         cmd->cdw11 = htole32(NVME_DSM_ATTR_DEALLOCATE);
 1740 }
 1741 
 1742 extern int nvme_use_nvd;
 1743 
 1744 #endif /* _KERNEL */
 1745 
 1746 /* Endianess conversion functions for NVMe structs */
 1747 static inline
 1748 void    nvme_completion_swapbytes(struct nvme_completion *s __unused)
 1749 {
 1750 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1751 
 1752         s->cdw0 = le32toh(s->cdw0);
 1753         /* omit rsvd1 */
 1754         s->sqhd = le16toh(s->sqhd);
 1755         s->sqid = le16toh(s->sqid);
 1756         /* omit cid */
 1757         s->status = le16toh(s->status);
 1758 #endif
 1759 }
 1760 
 1761 static inline
 1762 void    nvme_power_state_swapbytes(struct nvme_power_state *s __unused)
 1763 {
 1764 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1765 
 1766         s->mp = le16toh(s->mp);
 1767         s->enlat = le32toh(s->enlat);
 1768         s->exlat = le32toh(s->exlat);
 1769         s->idlp = le16toh(s->idlp);
 1770         s->actp = le16toh(s->actp);
 1771 #endif
 1772 }
 1773 
 1774 static inline
 1775 void    nvme_controller_data_swapbytes(struct nvme_controller_data *s __unused)
 1776 {
 1777 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1778         int i;
 1779 
 1780         s->vid = le16toh(s->vid);
 1781         s->ssvid = le16toh(s->ssvid);
 1782         s->ctrlr_id = le16toh(s->ctrlr_id);
 1783         s->ver = le32toh(s->ver);
 1784         s->rtd3r = le32toh(s->rtd3r);
 1785         s->rtd3e = le32toh(s->rtd3e);
 1786         s->oaes = le32toh(s->oaes);
 1787         s->ctratt = le32toh(s->ctratt);
 1788         s->rrls = le16toh(s->rrls);
 1789         s->crdt1 = le16toh(s->crdt1);
 1790         s->crdt2 = le16toh(s->crdt2);
 1791         s->crdt3 = le16toh(s->crdt3);
 1792         s->oacs = le16toh(s->oacs);
 1793         s->wctemp = le16toh(s->wctemp);
 1794         s->cctemp = le16toh(s->cctemp);
 1795         s->mtfa = le16toh(s->mtfa);
 1796         s->hmpre = le32toh(s->hmpre);
 1797         s->hmmin = le32toh(s->hmmin);
 1798         s->rpmbs = le32toh(s->rpmbs);
 1799         s->edstt = le16toh(s->edstt);
 1800         s->kas = le16toh(s->kas);
 1801         s->hctma = le16toh(s->hctma);
 1802         s->mntmt = le16toh(s->mntmt);
 1803         s->mxtmt = le16toh(s->mxtmt);
 1804         s->sanicap = le32toh(s->sanicap);
 1805         s->hmminds = le32toh(s->hmminds);
 1806         s->hmmaxd = le16toh(s->hmmaxd);
 1807         s->nsetidmax = le16toh(s->nsetidmax);
 1808         s->endgidmax = le16toh(s->endgidmax);
 1809         s->anagrpmax = le32toh(s->anagrpmax);
 1810         s->nanagrpid = le32toh(s->nanagrpid);
 1811         s->pels = le32toh(s->pels);
 1812         s->maxcmd = le16toh(s->maxcmd);
 1813         s->nn = le32toh(s->nn);
 1814         s->oncs = le16toh(s->oncs);
 1815         s->fuses = le16toh(s->fuses);
 1816         s->awun = le16toh(s->awun);
 1817         s->awupf = le16toh(s->awupf);
 1818         s->acwu = le16toh(s->acwu);
 1819         s->sgls = le32toh(s->sgls);
 1820         s->mnan = le32toh(s->mnan);
 1821         for (i = 0; i < 32; i++)
 1822                 nvme_power_state_swapbytes(&s->power_state[i]);
 1823 #endif
 1824 }
 1825 
 1826 static inline
 1827 void    nvme_namespace_data_swapbytes(struct nvme_namespace_data *s __unused)
 1828 {
 1829 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1830         int i;
 1831 
 1832         s->nsze = le64toh(s->nsze);
 1833         s->ncap = le64toh(s->ncap);
 1834         s->nuse = le64toh(s->nuse);
 1835         s->nawun = le16toh(s->nawun);
 1836         s->nawupf = le16toh(s->nawupf);
 1837         s->nacwu = le16toh(s->nacwu);
 1838         s->nabsn = le16toh(s->nabsn);
 1839         s->nabo = le16toh(s->nabo);
 1840         s->nabspf = le16toh(s->nabspf);
 1841         s->noiob = le16toh(s->noiob);
 1842         s->npwg = le16toh(s->npwg);
 1843         s->npwa = le16toh(s->npwa);
 1844         s->npdg = le16toh(s->npdg);
 1845         s->npda = le16toh(s->npda);
 1846         s->nows = le16toh(s->nows);
 1847         s->anagrpid = le32toh(s->anagrpid);
 1848         s->nvmsetid = le16toh(s->nvmsetid);
 1849         s->endgid = le16toh(s->endgid);
 1850         for (i = 0; i < 16; i++)
 1851                 s->lbaf[i] = le32toh(s->lbaf[i]);
 1852 #endif
 1853 }
 1854 
 1855 static inline
 1856 void    nvme_error_information_entry_swapbytes(
 1857     struct nvme_error_information_entry *s __unused)
 1858 {
 1859 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1860 
 1861         s->error_count = le64toh(s->error_count);
 1862         s->sqid = le16toh(s->sqid);
 1863         s->cid = le16toh(s->cid);
 1864         s->status = le16toh(s->status);
 1865         s->error_location = le16toh(s->error_location);
 1866         s->lba = le64toh(s->lba);
 1867         s->nsid = le32toh(s->nsid);
 1868         s->csi = le64toh(s->csi);
 1869         s->ttsi = le16toh(s->ttsi);
 1870 #endif
 1871 }
 1872 
 1873 static inline
 1874 void    nvme_le128toh(void *p __unused)
 1875 {
 1876 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1877         /* Swap 16 bytes in place */
 1878         char *tmp = (char*)p;
 1879         char b;
 1880         int i;
 1881         for (i = 0; i < 8; i++) {
 1882                 b = tmp[i];
 1883                 tmp[i] = tmp[15-i];
 1884                 tmp[15-i] = b;
 1885         }
 1886 #endif
 1887 }
 1888 
 1889 static inline
 1890 void    nvme_health_information_page_swapbytes(
 1891     struct nvme_health_information_page *s __unused)
 1892 {
 1893 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1894         int i;
 1895 
 1896         s->temperature = le16toh(s->temperature);
 1897         nvme_le128toh((void *)s->data_units_read);
 1898         nvme_le128toh((void *)s->data_units_written);
 1899         nvme_le128toh((void *)s->host_read_commands);
 1900         nvme_le128toh((void *)s->host_write_commands);
 1901         nvme_le128toh((void *)s->controller_busy_time);
 1902         nvme_le128toh((void *)s->power_cycles);
 1903         nvme_le128toh((void *)s->power_on_hours);
 1904         nvme_le128toh((void *)s->unsafe_shutdowns);
 1905         nvme_le128toh((void *)s->media_errors);
 1906         nvme_le128toh((void *)s->num_error_info_log_entries);
 1907         s->warning_temp_time = le32toh(s->warning_temp_time);
 1908         s->error_temp_time = le32toh(s->error_temp_time);
 1909         for (i = 0; i < 8; i++)
 1910                 s->temp_sensor[i] = le16toh(s->temp_sensor[i]);
 1911         s->tmt1tc = le32toh(s->tmt1tc);
 1912         s->tmt2tc = le32toh(s->tmt2tc);
 1913         s->ttftmt1 = le32toh(s->ttftmt1);
 1914         s->ttftmt2 = le32toh(s->ttftmt2);
 1915 #endif
 1916 }
 1917 
 1918 static inline
 1919 void    nvme_firmware_page_swapbytes(struct nvme_firmware_page *s __unused)
 1920 {
 1921 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1922         int i;
 1923 
 1924         for (i = 0; i < 7; i++)
 1925                 s->revision[i] = le64toh(s->revision[i]);
 1926 #endif
 1927 }
 1928 
 1929 static inline
 1930 void    nvme_ns_list_swapbytes(struct nvme_ns_list *s __unused)
 1931 {
 1932 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1933         int i;
 1934 
 1935         for (i = 0; i < 1024; i++)
 1936                 s->ns[i] = le32toh(s->ns[i]);
 1937 #endif
 1938 }
 1939 
 1940 static inline
 1941 void    nvme_command_effects_page_swapbytes(
 1942     struct nvme_command_effects_page *s __unused)
 1943 {
 1944 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1945         int i;
 1946 
 1947         for (i = 0; i < 256; i++)
 1948                 s->acs[i] = le32toh(s->acs[i]);
 1949         for (i = 0; i < 256; i++)
 1950                 s->iocs[i] = le32toh(s->iocs[i]);
 1951 #endif
 1952 }
 1953 
 1954 static inline
 1955 void    nvme_res_notification_page_swapbytes(
 1956     struct nvme_res_notification_page *s __unused)
 1957 {
 1958 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1959         s->log_page_count = le64toh(s->log_page_count);
 1960         s->nsid = le32toh(s->nsid);
 1961 #endif
 1962 }
 1963 
 1964 static inline
 1965 void    nvme_sanitize_status_page_swapbytes(
 1966     struct nvme_sanitize_status_page *s __unused)
 1967 {
 1968 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1969         s->sprog = le16toh(s->sprog);
 1970         s->sstat = le16toh(s->sstat);
 1971         s->scdw10 = le32toh(s->scdw10);
 1972         s->etfo = le32toh(s->etfo);
 1973         s->etfbe = le32toh(s->etfbe);
 1974         s->etfce = le32toh(s->etfce);
 1975         s->etfownd = le32toh(s->etfownd);
 1976         s->etfbewnd = le32toh(s->etfbewnd);
 1977         s->etfcewnd = le32toh(s->etfcewnd);
 1978 #endif
 1979 }
 1980 
 1981 static inline
 1982 void    intel_log_temp_stats_swapbytes(struct intel_log_temp_stats *s __unused)
 1983 {
 1984 #if _BYTE_ORDER != _LITTLE_ENDIAN
 1985 
 1986         s->current = le64toh(s->current);
 1987         s->overtemp_flag_last = le64toh(s->overtemp_flag_last);
 1988         s->overtemp_flag_life = le64toh(s->overtemp_flag_life);
 1989         s->max_temp = le64toh(s->max_temp);
 1990         s->min_temp = le64toh(s->min_temp);
 1991         /* omit _rsvd[] */
 1992         s->max_oper_temp = le64toh(s->max_oper_temp);
 1993         s->min_oper_temp = le64toh(s->min_oper_temp);
 1994         s->est_offset = le64toh(s->est_offset);
 1995 #endif
 1996 }
 1997 
 1998 static inline
 1999 void    nvme_resv_status_swapbytes(struct nvme_resv_status *s __unused,
 2000     size_t size __unused)
 2001 {
 2002 #if _BYTE_ORDER != _LITTLE_ENDIAN
 2003         u_int i, n;
 2004 
 2005         s->gen = le32toh(s->gen);
 2006         n = (s->regctl[1] << 8) | s->regctl[0];
 2007         n = MIN(n, (size - sizeof(s)) / sizeof(s->ctrlr[0]));
 2008         for (i = 0; i < n; i++) {
 2009                 s->ctrlr[i].ctrlr_id = le16toh(s->ctrlr[i].ctrlr_id);
 2010                 s->ctrlr[i].hostid = le64toh(s->ctrlr[i].hostid);
 2011                 s->ctrlr[i].rkey = le64toh(s->ctrlr[i].rkey);
 2012         }
 2013 #endif
 2014 }
 2015 
 2016 static inline
 2017 void    nvme_resv_status_ext_swapbytes(struct nvme_resv_status_ext *s __unused,
 2018     size_t size __unused)
 2019 {
 2020 #if _BYTE_ORDER != _LITTLE_ENDIAN
 2021         u_int i, n;
 2022 
 2023         s->gen = le32toh(s->gen);
 2024         n = (s->regctl[1] << 8) | s->regctl[0];
 2025         n = MIN(n, (size - sizeof(s)) / sizeof(s->ctrlr[0]));
 2026         for (i = 0; i < n; i++) {
 2027                 s->ctrlr[i].ctrlr_id = le16toh(s->ctrlr[i].ctrlr_id);
 2028                 s->ctrlr[i].rkey = le64toh(s->ctrlr[i].rkey);
 2029                 nvme_le128toh((void *)s->ctrlr[i].hostid);
 2030         }
 2031 #endif
 2032 }
 2033 
 2034 static inline void
 2035 nvme_device_self_test_swapbytes(struct nvme_device_self_test_page *s __unused)
 2036 {
 2037 #if _BYTE_ORDER != _LITTLE_ENDIAN
 2038         uint8_t *tmp;
 2039         uint32_t r, i;
 2040         uint8_t b;
 2041 
 2042         for (r = 0; r < 20; r++) {
 2043                 s->result[r].poh = le64toh(s->result[r].poh);
 2044                 s->result[r].nsid = le32toh(s->result[r].nsid);
 2045                 /* Unaligned 64-bit loads fail on some architectures */
 2046                 tmp = s->result[r].failing_lba;
 2047                 for (i = 0; i < 4; i++) {
 2048                         b = tmp[i];
 2049                         tmp[i] = tmp[7-i];
 2050                         tmp[7-i] = b;
 2051                 }
 2052         }
 2053 #endif
 2054 }
 2055 #endif /* __NVME_H__ */

Cache object: 31b6084752b99cd631f3c37a120d7169


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.