1/* $NetBSD: nvmeio.h,v 1.4 2021/11/10 17:19:30 msaitoh Exp $ */ 2 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: head/sys/dev/nvme/nvme.h 329824 2018-02-22 13:32:31Z wma $ 29 */ 30 31#ifndef __NVMEIO_H__ 32#define __NVMEIO_H__ 33 34#include <sys/endian.h> 35#include <sys/ioccom.h> 36#include <dev/ic/nvmereg.h> 37 38#define NVME_PASSTHROUGH_CMD _IOWR('n', 0, struct nvme_pt_command) 39 40#define nvme_completion_is_error(cpl) \ 41 ((NVME_CQE_SC((cpl)->flags) != NVME_CQE_SC_SUCCESS) \ 42 || (NVME_CQE_SCT((cpl)->flags) != NVME_CQE_SCT_GENERIC)) 43 44struct nvme_pt_command { 45 46 /* 47 * cmd is used to specify a passthrough command to a controller or 48 * namespace. 49 * 50 * The following fields from cmd may be specified by the caller: 51 * * opcode 52 * * nsid (namespace id) - for admin commands only 53 * * cdw10-cdw15 54 * 55 * Remaining fields must be set to 0 by the caller. 56 */ 57 struct nvme_sqe cmd; 58 59 /* 60 * cpl returns completion status for the passthrough command 61 * specified by cmd. 62 * 63 * The following fields will be filled out by the driver, for 64 * consumption by the caller: 65 * * cdw0 66 * * flags (except for phase) 67 * 68 * Remaining fields will be set to 0 by the driver. 69 */ 70 struct nvme_cqe cpl; 71 72 /* buf is the data buffer associated with this passthrough command. */ 73 void *buf; 74 75 /* 76 * len is the length of the data buffer associated with this 77 * passthrough command. 78 */ 79 uint32_t len; 80 81 /* 82 * is_read = 1 if the passthrough command will read data into the 83 * supplied buffer from the controller. 84 * 85 * is_read = 0 if the passthrough command will write data from the 86 * supplied buffer to the controller. 87 */ 88 uint32_t is_read; 89 90 /* 91 * timeout (unit: ms) 92 * 93 * 0: use default timeout value 94 */ 95 uint32_t timeout; 96}; 97 98/* Endianness conversion functions for NVMe structs */ 99static __inline void 100nvme_le128toh(uint64_t v[2]) 101{ 102#if _BYTE_ORDER != _LITTLE_ENDIAN 103 uint64_t t; 104 105 t = le64toh(v[0]); 106 v[0] = le64toh(v[1]); 107 v[1] = t; 108#endif 109} 110 111static __inline void 112nvme_namespace_format_swapbytes(struct nvm_namespace_format *format) 113{ 114 115#if _BYTE_ORDER != _LITTLE_ENDIAN 116 format->ms = le16toh(format->ms); 117#endif 118} 119 120static __inline void 121nvme_identify_namespace_swapbytes(struct nvm_identify_namespace *identify) 122{ 123#if _BYTE_ORDER != _LITTLE_ENDIAN 124 u_int i; 125 126 identify->nsze = le64toh(identify->nsze); 127 identify->ncap = le64toh(identify->ncap); 128 identify->nuse = le64toh(identify->nuse); 129 identify->nawun = le16toh(identify->nawun); 130 identify->nawupf = le16toh(identify->nawupf); 131 identify->nacwu = le16toh(identify->nacwu); 132 identify->nabsn = le16toh(identify->nabsn); 133 identify->nabo = le16toh(identify->nabo); 134 identify->nabspf = le16toh(identify->nabspf); 135 identify->noiob = le16toh(identify->noiob); 136 for (i = 0; i < __arraycount(identify->lbaf); i++) 137 nvme_namespace_format_swapbytes(&identify->lbaf[i]); 138#endif 139} 140 141static __inline void 142nvme_identify_psd_swapbytes(struct nvm_identify_psd *psd) 143{ 144 145#if _BYTE_ORDER != _LITTLE_ENDIAN 146 psd->mp = le16toh(psd->mp); 147 psd->enlat = le32toh(psd->enlat); 148 psd->exlat = le32toh(psd->exlat); 149 psd->idlp = le16toh(psd->idlp); 150 psd->actp = le16toh(psd->actp); 151 psd->ap = le16toh(psd->ap); 152#endif 153} 154 155static __inline void 156nvme_identify_controller_swapbytes(struct nvm_identify_controller *identify) 157{ 158#if _BYTE_ORDER != _LITTLE_ENDIAN 159 u_int i; 160 161 identify->vid = le16toh(identify->vid); 162 identify->ssvid = le16toh(identify->ssvid); 163 identify->cntlid = le16toh(identify->cntlid); 164 identify->ver = le32toh(identify->ver); 165 identify->rtd3r = le32toh(identify->rtd3r); 166 identify->rtd3e = le32toh(identify->rtd3e); 167 identify->oaes = le32toh(identify->oaes); 168 identify->ctrattr = le32toh(identify->ctrattr); 169 identify->oacs = le16toh(identify->oacs); 170 identify->wctemp = le16toh(identify->wctemp); 171 identify->cctemp = le16toh(identify->cctemp); 172 identify->mtfa = le16toh(identify->mtfa); 173 identify->hmpre = le32toh(identify->hmpre); 174 identify->hmmin = le32toh(identify->hmmin); 175 nvme_le128toh(identify->untncap.tnvmcap); 176 nvme_le128toh(identify->untncap.unvmcap); 177 identify->rpmbs = le32toh(identify->rpmbs); 178 identify->edstt = le16toh(identify->edstt); 179 identify->kas = le16toh(identify->kas); 180 identify->hctma = le16toh(identify->hctma); 181 identify->mntmt = le16toh(identify->mntmt); 182 identify->mxtmt = le16toh(identify->mxtmt); 183 identify->sanicap = le32toh(identify->sanicap); 184 identify->maxcmd = le16toh(identify->maxcmd); 185 identify->nn = le32toh(identify->nn); 186 identify->oncs = le16toh(identify->oncs); 187 identify->fuses = le16toh(identify->fuses); 188 identify->awun = le16toh(identify->awun); 189 identify->awupf = le16toh(identify->awupf); 190 identify->acwu = le16toh(identify->acwu); 191 identify->sgls = le32toh(identify->sgls); 192 for (i = 0; i < __arraycount(identify->psd); i++) 193 nvme_identify_psd_swapbytes(&identify->psd[i]); 194#endif 195} 196 197#endif /* __NVMEIO_H__ */ 198